Saturday, June 25, 2005

 

UNIX Library Functions

The UNIX system provides a large number of C functions as libraries. Some of these implement frequently used operations, while others are very specialised in their application.
Wise programmers will check whether a library function is available to perform a task before writing their own version. This will reduce program development time. The library functions have been tested, so they are more likely to be correct than any function which the programmer might write. This will save time when debugging the program.

Finding Information about Library Functions

The UNIX manual has an entry for all available functions. Function documentation is stored in section 3 of the manual, and there are many other useful system calls in section 2. If you already know the name of the function you want, you can read the page by typing (to find about strcat).
man 3 strcatIf you don't know the name of the function, a full list is included in the introductory page for section 3 of the manual. To read this, type
man 3 intro
There are approximately 700 functions described here. This number tends to increase with each upgrade of the system.
On any manual page, the SYNOPSIS section will include information on the use of the function. For example
#include
char *ctime(time_t *clock)
This means that you must have
#include in your file before you call ctime. And that function ctime takes a pointer to type time_t as an argument, and returns a string (char *). time_t will probably be defined in the same manual page.
The DESCRIPTION section will then give a short description of what the function does. For example
ctime() converts a long integer, pointed to by clock, to a
26-character string of the form produced by asctime().
Further related reading is suggested in the SEE ALSO section.

Use of Library Functions

To use a function, ensure that you have made the required #includes in your C file. Then the function can be called as though you had defined it yourself.
It is important to ensure that your arguments have the expected types, otherwise the function will probably produce strange results. lint is quite good at checking such things.
Some libraries require extra options before the compiler can support their use. For example, to compile a program including functions from the math.h library the command might be
cc mathprog.c -o mathprog -lm
The final -lm is an instruction to link the maths library with the program. The manual page for each function will usually inform you if any special compiler flags are required.

Some Useful Library Functions

The following functions may be useful to you. Each manual page typically describes several functions, so if you see something similar to what you want, try looking in that manual page.

abs -------- integer absolute value
ctime ------ convert date and time
fopen ------ open a stream
printf ------ formatted output
fputc ------ put character or word on a stream
getwd ----- get current working directory path name
strcat ----- string concatenation
ctype ------ character classification and conversion macros and functions
maktemp -- make a unique file name
puts ------- put a string on a stream
sleep ------ suspend execution for interval
stdio ------ standard buffered input/output pakage

To get a full summary type
man 3 intro


Friday, June 24, 2005

 

Programs with Several Files

When writing a large program, you may find it convenient to split it several source files. This has several advantages, but makes compilation more complicated.
This section will discuss advantages and disadvantages of using several files in a program, and advise you on how to divide a program between several files, should you wish to do so.

Advantages of Using Several Files

The main advantages of spreading a program across several files are:
Teams of programmers can work on programs. Each programmer works on a different file.
An object oriented style can be used. Each file defines a particular type of object as a datatype and operations on that object as functions. The implementation of the object can be kept private from the rest of the program. This makes for well structured programs which are easy to maintain.
Files can contain all functions from a related group. For Example all matrix operations. These can then be accessed like a function library.
Well implemented objects or function definitions can be re-used in other programs, reducing development time.
In very large programs each major function can occupy a file to itself. Any lower level functions used to implement them can be kept in the same file. Then programmers who call the major function need not be distracted by all the lower level work.
When changes are made to a file, only that file need be re-compiled to rebuild the program. The UNIX make facility is very useful for rebuilding multi-file programs in this way.

How to Divide a Program between Several Files

Where a function is spread over several files, each file will contain one or more functions. One file will include main while the others will contain functions which are called by others. These other files can be treated as a library of functions.
Programmers usually start designing a program by dividing the problem into easily managed sections. Each of these sections might be implemented as one or more functions. All functions from each section will usually live in a single file.
Where objects are implemented as data structures, it is usual to to keep all functions which access that object in the same file. The advantages of this are;
The object can easily be re-used in other programs.
All related functions are stored together.
Later changes to the object require only one file to be modified.
Where the file contains the definition of an object, or functions which return values, there is a further restriction on calling these functions from another file. Unless functions in another file are told about the object or function definitions, they will be unable to compile them correctly.
The best solution to this problem is to write a header file for each of the C files. This will have the same name as the C file, but ending in .h. The header file contains definitions of all the functions used in the C file.
Whenever a function in another file calls a function from our C file, it can define the function by making a #include of the appropriate .h file.

Organisation of Data in each File

Any file must have its data organised in a certain order. This will typically be:
A preamble consisting of #defined constants, #included header files and typedefs of important datatypes.
Declaration of global and external variables. Global variables may also be initialised here.
One or more functions.
The order of items is important, since every object must be defined before it can be used. Functions which return values must be defined before they are called. This definition might be one of the following:
Where the function is defined and called in the same file, a full declaration of the function can be placed ahead of any call to the function.
If the function is called from a file where it is not defined, a prototype should appear before the call to the function. A function defined as
float find_max(float a, float b, float c)
{ /* etc ... ... */

would have a prototype of
float find_max(float a, float b, float c);
The prototype may occur among the global variables at the start of the source file. Alternatively it may be declared in a header file which is read in using a #include.
It is important to remember that all C objects should be declared before use.

Compiling Multi-File Programs

This process is rather more involved than compiling a single file program. Imagine a program in three files prog.c, containing main(), func1.c and func2.c. The simplest method of compilation (to produce a runnable file called a.out) would be
cc prog.c func1.c func2.c
If we wanted to call the runnable file prog we would have to type
cc prog.c func1.c func2.c -o prog
In these examples, each of the .c files is compiled, and then they are automatically linked together using a program called the loader ld.

Separate Compilation

We can also compile each C file separately using the cc -c option. This produces an object file with the same name, but ending in .o. After this, the object files are linked using the linker. This would require the four following commands for our current example.
cc -c prog.c
cc -c func1.c
cc -c func2.c
ld prog.o func1.o func2.o -o prog

Each file is compiled before the object files are linked to give a runnable file.
The advantage of separate compilation is that only files which have been edited since the last compilation need to be re-compiled when re-building the program. For very large programs this can save a lot of time.
The make utility is designed to automate this re-building process. It checks the times of modification of files, and selectively re-compiles as required. It is an excellent tool for maintaining multi-file programs. Its use is recommended when building multi-file programs.

Using make with Multi-File Programs

We have already used make to build single file programs. It was really designed to help build large multi-file programs. Its use will be described here.
Make knows about `dependencies' in program building. For example;
We can get prog.o by running cc -c prog.c.
This need only be done if prog.c changed more recently than prog.o. make is usually used with a configuration file called Makefile which describes the structure of the program. This includes the name of the runnable file, and the object files to be linked to create it. Here is a sample Makefile for our current example
# Sample Makefile for prog
#
# prog is built from prog.c func1.c func2.c
#
# Object files (Ending in .o,
# these are compiled from .c files by make)
OBJS = prog.o func1.o func2.o
# Prog is generated from the object files
prog: $(OBJS)
$(CC) $(CFLAGS) -o prog $(OBJS)
# ^^^ This space must be a TAB.
# Above line is an instruction to link object files
This looks cluttered, but ignore the comments (lines starting with #) andthere are just 3 lines.
When make is run, Makefile is searched for a list of dependencies. The compiler is involved to create .o files where needed. The link statement is then used to create the runnable file.
make re-builds the whole program with a minimum of re-compilation, and ensures that all parts of the program are up to date. It has many other features, some of which are very complicated.
For a full description of all of these features, look at the manual page for make by typing
man make


Thursday, June 23, 2005

 

The C Preprocessor

The C preprocessor is a tool which filters your source code before it is compiled. The preprocessor allows constants to be named using the #define notation. The preprocessor provides several other facilities which will be described here. It is particularly useful for selecting machine dependent pieces of code for different computer types, allowing a single program to be compiled and run on several different computers.
The C preprocessor isn't restricted to use with C programs, and programmers who use other languages may also find it useful, however it is tuned to recognise features of the C language like comments and strings, so its use may be restricted in other circumstances.
The preprocessor is called cpp, however it is called automatically by the compiler so you will not need to call it while programming in C.

Using #define to Implement Constants

We have already met this facility, in its simplest form it allows us to define textual substitutions as follows.
#define MAXSIZE 256
This will lead to the value 256 being substituted for each occurrence of the word MAXSIZE in the file.

Using #define to Create Functional Macros

#define can also be given arguments which are used in its replacement. The definitions are then called macros. Macros work rather like functions, but with the following minor differences.
Since macros are implemented as a textual substitution, there is no effect on program performance (as with functions).
Recursive macros are generally not a good idea.
Macros don't care about the type of their arguments. Hence macros are a good choice where we might want to operate on reals, integers or a mixture of the two. Programmers sometimes call such type flexibility polymorphism.
Macros are generally fairly small. Macros are full of traps for the unwary programmer. In particular the textual substitution means that arithmetic expressions are liable to be corrupted by the order of evaluation rules.
Here is an example of a macro which won't work.
#define DOUBLE(x) x+x
Now if we have a statement
a = DOUBLE(b) * c;
This will be expanded to
a = b+b * c;
And since * has a higher priority than +, the compiler will treat it as.
a = b + (b * c);
The problem can be solved using a more robust definition of DOUBLE
#define DOUBLE(x) (x+x)
Here the brackets around the definition force the expression to be evaluated before any surrounding operators are applied. This should make the macro more reliable.
In general it is better to write a C function than risk using a macro.

Reading in Other Files using #include

The preprocessor directive #include is an instruction to read in the entire contents of another file at that point. This is generally used to read in header files for library functions. Header files contain details of functions and types used within the library. They must be included before the program can make use of the library functions.
Library header file names are enclosed in angle brackets, < >. These tell the preprocessor to look for the header file in the standard location for library definitions. This is /usr/include for most UNIX systems.
For example
#include
Another use for #include for the programmer is where multi-file programs are being written. Certain information is required at the beginning of each program file. This can be put into a file called globals.h and included in each program file. Local header file names are usually enclosed by double quotes, " ". It is conventional to give header files a name which ends in .h to distinguish them from other types of file.
Our globals.h file would be included by the following line.
#include "globals.h"

Conditional selection of code using #ifdef

The preprocessor has a conditional statement similar to C's if else. It can be used to selectively include statements in a program. This is often used where two different computer types implement a feature in different ways. It allows the programmer to produce a program which will run on either type.
The keywords for conditional selection are; #ifdef, #else and #endif.
#ifdef
takes a name as an argument, and returns true if the the name has a current definition. The name may be defined using a #define, the -d option of the compiler, or certain names which are automatically defined by the UNIX environment.
#else
is optional and ends the block beginning with #ifdef. It is used to create a 2 way optional selection.
#endif
ends the block started by #ifdef or #else.
Where the #ifdef is true, statements between it and a following #else or #endif are included in the program. Where it is false, and there is a following #else, statements between the #else and the following #endif are included.
This is best illustrated by an example.

Using #ifdef for Different Computer Types

Conditional selection is rarely performed using #defined values. A simple application using machine dependent values is illustrated below.
#include
main()
{
#ifdef vax
printf("This is a VAX\n");
#endif
#ifdef sun
printf("This is a SUN\n");
#endif
}
sun is defined automatically on SUN computers. vax is defined automatically on VAX computers.

Using #ifdef to Temporarily Remove Program Statements

#ifdef also provides a useful means of temporarily `blanking out' lines of a program. The lines in question are preceeded by #ifdef NEVER and followed by #endif. Of course you should ensure that the name NEVER isn't defined anywhere.
The preprocessor has several other useful facilities. If you are interested in these you can read more by typing
man cpp


Wednesday, June 22, 2005

 

Structures in C

A structure is a collection of variables under a single name. These variables can be of different types, and each has a name which is used to select it from the structure. A structure is a convenient way of grouping several pieces of related information together.
A structure can be defined as a new named type, thus extending the number of available types. It can use other structures, arrays or pointers as some of its members, though this can get complicated unless you are careful.

Defining a Structure

A structure type is usually defined near to the start of a file using a typedef statement. typedef defines and names a new type, allowing its use throughout the program. typedefs usually occur just after the #define and #include statements in a file.
Here is an example structure definition.
typedef struct {
char name[64];
char course[128];
int age;
int year;
} student;
This defines a new type student variables of type student can be declared as follows.
student st_rec;Notice how similar this is to declaring an int or float.
The variable name is st_rec, it has members called name, course, age and year.

Accessing Members of a Structure

Each member of a structure can be used just like a normal variable, but its name will be a bit longer. To return to the examples above, member name of structure st_rec will behave just like a normal array of char, however we refer to it by the name
st_rec.name
Here the dot is an operator which selects a member from a structure.
Where we have a pointer to a structure we could dereference the pointer and then use dot as a member selector. This method is a little clumsy to type. Since selecting a member from a structure pointer happens frequently, it has its own operator -> which acts as follows. Assume that st_ptr is a pointer to a structure of type student We would refer to the name member as
st_ptr -> name

Structures as Function Arguments

A structure can be passed as a function argument just like any other variable. This raises a few practical issues.
Where we wish to modify the value of members of the structure, we must pass a pointer to that structure. This is just like passing a pointer to an int type argument whose value we wish to change.
If we are only interested in one member of a structure, it is probably simpler to just pass that member. This will make for a simpler function, which is easier to re-use. Of course if we wish to change the value of that member, we should pass a pointer to it.
When a structure is passed as an argument, each member of the structure is copied. This can prove expensive where structures are large or functions are called frequently. Passing and working with pointers to large structures may be more efficient in such cases.

Further Uses of Structures

As we have seen, a structure is a good way of storing related data together. It is also a good way of representing certain types of information. Complex numbers in mathematics inhabit a two dimensional plane (stretching in real and imaginary directions). These could easily be represented here by
typedef struct {
double real;
double imag;
} complex;
doubles have been used for each field because their range is greater than floats and because the majority of mathematical library functions deal with doubles by default.
In a similar way, structures could be used to hold the locations of points in multi-dimensional space. Mathematicians and engineers might see a storage efficient implementation for sparse arrays here.
Apart from holding data, structures can be used as members of other structures. Arrays of structures are possible, and are a good way of storing lists of data with regular fields, such as databases.
Another possibility is a structure whose fields include pointers to its own type. These can be used to build chains (programmers call these linked lists), trees or other connected structures. These are rather daunting to the new programmer, so we won't deal with them here.


Tuesday, June 21, 2005

 

Handling Files in C (3)

3)Special Characters

C makes use of some 'invisible' characters which have already been mentioned. However a fuller description seems appropriate here.

NULL, The Null Pointer or Character

NULL is a character or pointer value. If a pointer, then the pointer variable does not reference any object (i.e. a pointer to nothing). It is usual for functions which return pointers to return NULL if they failed in some way. The return value can be tested. See the section on fopen for an example of this.
NULL is returned by read commands of the gets family when they try to read beyond the end of an input file.
Where it is used as a character, NULL is commonly written as '\0'. It is the string termination character which is automatically appended to any strings in your C program. You usually need not bother about this final \0', since it is handled automatically. However it sometimes makes a useful target to terminate a string search. There is an example of this in the string_length function example in the section on Functions in C.

EOF, The End of File Marker

EOF is a character which indicates the end of a file. It is returned by read commands of the getc and scanf families when they try to read beyond the end of a file.

4)Other String Handling Functions

As well as sprintf and sscanf, the UNIX system has a number of other string handling functions within its libraries. A number of the most useful ones are contained in the file, and are made available by putting the line

#include "strings.h" near to the head of your program file.

A couple of the functions are described below.

strcpy (str1, str2) copies str2 into str1.
strcmp (str1, str2) compares the contents of str1 and str2. Return 0 (false) if both are equal

A full list of these functions can be seen using the man command by typing

man 3 strings

5)Conclusion

The variety of different types of input and output, using standard input or output, files or character strings make C a very powerful language. The addition of character input and output make it highly suitable for applications where the format of data must be controlled very precisely.


 

Handling Files in C (2)

3)Input and Output using file pointers

Having opened a file pointer, you will wish to use it for either input or output. C supplies a set of functions to allow you to do this. All are very similar to input and output functions that you have already met.

Character Input and Output with Files

This is done using equivalents of getchar and putchar which are called getc and putc. Each takes an extra argument, which identifies the file pointer to be used for input or output.

putchar(c) is equivalent to putc(c, stdout)
getchar( ) is equivalent to getc(stdin)

Formatted Input Output with File Pointers

Similarly there are equivalents to the functions printf and scanf which read or write data to files. These are called fprintf and fscanf. You have already seen fprintf being used to write data to stderr.
The functions are used in the same way, except that the fprintf and fscanf take the file pointer as an additional first argument.

Formatted Input Output with Strings

These are the third set of the printf and scanf families. They are called sprintf and sscanf.

sprintf
puts formatted data into a string which must have sufficient space allocated to hold it. This can be done by declaring it as an array of char. The data is formatted according to a control string of the same form as that for p rintf.
sscanf
takes data from a string and stores it in other variables as specified by the control string. This is done in the same way that scanf reads input data into variables. sscanf is very useful for converting strings into numeric v values.

Whole Line Input and Output using File Pointers

Predictably, equivalents to gets and puts exist called fgets and fputs. The programmer should be careful in using them, since they are incompatible with gets and puts. gets requires the programmer to specify the maximum number of characters to be read. fgets and fputs retain the trailing newline character on the line they read or write, wheras gets and puts discard the newline.

When transferring data from files to standard input / output channels, the simplest way to avoid incompatibility with the newline is to use fgets and fputs for files and standard channels too.
For Example, read a line from the keyboard using

fgets(data_string, 80, stdin);
and write a line to the screen using
fputs(data_string, stdout);


 

Handling Files in C (1)

This section describes the use of C's input / output facilities for reading
and writing files. There is also a brief description of string handling
functions here.
The functions are all variants on the forms of input / output which were
introduced in the previous section.

1)UNIX File Redirection

UNIX has a facility called redirection which allows a program to access a single
input file and a single output file very easily. The program is written to read
from the keyboard and write to the terminal screen as normal.
To run prog1 but read data from file infile instead of the keyboard, you would
type
prog1< infile
To run prog1 and write data to outfile instead of the screen, you would type
prog1> outfile
Both can also be combined as in
prog1<infile > outfile
Redirection is simple, and allows a single program to read or write data to or
from files or the screen and keyboard.
Some programs need to access several files for input or output, redirection
cannot do this. In such cases you will have to use C's file handling facilities.

2)C File Handling

File Pointers

C communicates with files using a new datatype called a file pointer. This type
is defined within stdio.h, and written as FILE *. A file pointer called
output_file is declared in a statement like
FILE *output_file;

Opening a file pointer using fopen

Your program must open a file before it can access it. This is done using the
fopen function, which returns the required file pointer. If the file cannot be
opened for any reason then the value NULL will be returned. You will usually use
fopen as follows
if ((output_file = fopen("output_file", "w")) == NULL)
fprintf(stderr, "Cannot open %s\n", "output_file");

fopen takes two arguments, both are strings, the first is the name of the file
to be opened, the second is an access character, which is usually one of:
w, open a file for writing
r, open a file for reading
a, open a file for appending

As usual, use the man command for further details by typing man fopen.

Standard file pointers in UNIX

UNIX systems provide three file descriptors which are automatically open to all C programs. These are

stdin: standard input, the keyboard or a redirected input file
stdout: standard output, the screen or a redirected output file
stderr: standard error, this is screen, or even output is redirected

Since these files are already open, there is no need to use fopen on them.

Closing a file using fclose

The fclose command can be used to disconnect a file pointer from a file. This is usually done so that the pointer can be used to access a different file. Systems have a limit on the number of files which can be open simultaneously, so it is a good idea to close a file when you have finished using it.
This would be done using a statement like
fclose(output_file);
If files are still open when a program exits, the system will close them for you. However it is usually better to close the files properly.


Monday, June 20, 2005

 

The Standard Input Output File (3)

Whole Lines of Input and Output

Where we are not too interested in the format of our data, or perhaps we cannot predict its format in advance, we can read and write whole lines as character strings. This approach allows us to read in a line of input, and then use various string handling functions to analyse it at our leisure.

1)gets

gets reads a whole line of input into a string until a newline or EOF is encountered. It is critical to ensure that the string is large enough to hold any expected input lines.
When all input is finished, NULL as defined in stdio.h is returned.

2)puts

puts writes a string to the output, and follows it with a newline character.
Example: Program which uses gets and puts to double space typed input.

#include "stdio.h"
main()
{ char line[256]; /* Define string sufficiently large to
store a line of input */
while(gets(line) != NULL) /* Read line */
{ puts(line); /* Print line */
printf("\n"); /* Print blank line */
}
}
Note that putchar, printf and puts can be freely used together. So can getchar, scanf and gets.


 

The Standard Input Output File (2)

Formatted Input / Output

We have met these functions earlier in the course. They are closest to the facilities offered by Pascal or Fortran, and usually the easiest to use for input and output. The versions offered under C are a little more detailed, offering precise control of layout.

1)printf

This offers more structured output than putchar. Its arguments are, in order; a control string, which controls what gets printed, followed by a list of values to be substituted for entries in the control string.

%d, A Decimal Integer
%f, A Float Point Value
%c, A Character
%s, A String

There are several more types available. For full details type
man printf
on your UNIX system.

It is also possible to insert numbers into the control string to control field widths for values to be displayed. For example %6d would print a decimal value in a field 6 spaces wide, %8.2f would print a real value in a field 8 spaces wide with room to show 2 decimal places. Display is left justified by default, but can be right justified by putting a - before the format information, for example %-6d, a decimal integer right justified in a 6 space field.

2)scanf

scanf allows formatted reading of data from the keyboard. Like printf it has a control string, followed by the list of items to be read. However scanf wants to know the address of the items to be read, since it is a function which will change that value. Therefore the names of variables are preceeded by the & sign. Character strings are an exception to this. Since a string is already a character pointer, we give the names of string variables unmodified by a leading &.

Control string entries which match values to be read are preceeded by the percentage sign in a similar way to their printf equivalents.

Type man scanf for details of all options on your system.




 

The Standard Input Output File (1)

The Standard Input Output File

UNIX supplies a standard package for performing input and output to files or the terminal. This contains most of the functions which will be introduced in this section, along with definitions of the datatypes required to use them. To use these facilities, your program must include these definitions by adding the line This is done by adding the line
#include <stdio.h>
near the start of the program file.
If you do not do this, the compiler may complain about undefined functions or datatypes.

Character Input / Output

This is the lowest level of input and output. It provides very precise control, but is usually too fiddly to be useful. Most computers perform buffering of input and output. This means that they'll not start reading any input until the return key is pressed, and they'll not print characters on the terminal until there is a whole line to be printed.

1)getchar

getchar returns the next character of keyboard input as an int. If there is an
error then EOF (end of file) is returned instead. It is therefore usual to
compare this value against EOF before using it. If the return value is stored in
a char, it will never be equal to EOF, so error conditions will not be handled
correctly.

As an example, here is a program to count the number of characters read until an
EOF is encountered. EOF can be generated by typing Control - d.

#include <stdio.h>

main()
{

int ch, i = 0;
while((ch = getchar()) != EOF)
i ++;

printf("%d\n", i);
}

2)putchar

putchar puts its character argument on the standard output (usually the
screen).

The following example program converts any typed input into capital letters.
To do this it applies the function toupper from the character conversion library
ctype.h to each character in turn.

#include <ctype.h> /* For definition of toupper */
#include <stdio.h> /* For definition of getchar, putchar, EOF */
main()
{ int ch;
while((ch = getchar()) != EOF)
putchar(toupper(ch));
}


Sunday, June 19, 2005

 

Pointer Again

In some case, pointer seems is the only way to reach the goal. Especially, when we need to change the value by calling the funcion. If the variable in the function is a local variable, changeing it does not change the value of variable calling in. One efficient solution is use pointer variable in that funcion. When we change the value to which the pointer points, It means we change the value in the memory.
But keep in mind, even when we use pointer, we still can not just change the address varibale "ptr", rather we should changed the "*ptr".
For example.

#include

void swap(int *p1,int *p2);

main()
{
int x1=100,x2=200;

printf("x1=%d,x2=%d\n",x1,x2);
swap(&x1,&amp;x2);
printf("x1=%d,x2=%d\n",x1,x2);
}

void swap(int *p1,int *p2)
{
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
//The following code is wrong
void swap(int *p1,int *p2)
{
int *temp;
temp=p1;
p1=p2;
p2=temp;
}

 

Share Candies

"分糖问题。有10个人围成一圈,每个任取若干块糖。若手里有奇数块糖则从糖堆里再拿一块,然后将手中糖的一半送下一个人。重复上述过程,直到大家手里的糖块相等。试设计程序模拟此过程。"

#include "stdio.h"

void share1 (int *candy);
int main ()
{

int i, ary[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *j;
int tmp=0;
j=ary;
for(i=0; i<10; i++)
printf ("%d", *(j+i));
printf("\n");

while ( (j[0]!=j[1])(j[0]!=j[2])(j[0]!=j[3])(j[0]!=j[4])
(j[0]!=j[5])(j[0]!=j[6])(j[0]!=j[7])(j[0]!=j[8])
(j[0]!=j[9]) )
{
j[0]=j[0]+tmp;
share1 (j); //here use j instead of *j,
// because in the function share1,
//"integer type pointer variable" candy is an address variable
tmp=j[9];
for(i=0; i<10; i++)
printf ("%d", *(j+i));
printf ("\n");
}
}
void share1 (int *candy)
{
int i;
{
for (i=0; i<9; i++)
{
if ((candy[i]%2)!=0)
candy[i]=(candy[i]+1)/2;
else
candy[i]=candy[i]/2;
candy[i+1]= candy[i+1]+candy[i];
}
if (candy[9]%2!=0)
candy[9]=(candy[9]+1)/2;
else candy[9] /=2;
}
}


This page is powered by Blogger. Isn't yours?