Author : Brian Kernighan
Page : << Previous 5 Next >>
do
another loop, otherwise get on with the next statement. As
with the while, the for loop may be done zero times. If the
expression is left out, it is taken to be always true, so
for( ; ; ) ...
and
while( 1 ) ...
are both infinite loops.
You might ask why we use a for since it's so much like
a while. (You might also ask why we use a while because...)
The for is usually preferable because it keeps the code
where it's used and sometimes eliminates the need for com-
pound statements, as in this code that zeros a two-
dimensional array:
for( i=0; i<n; i++ )
for( j=0; j<m; j++ )
array[i][j] = 0;
Suppose we want, as part of a larger program, to count
the occurrences of the ascii characters in some input text.
Let us also map illegal characters (those with value>127 or
<0) into one pile. Since this is presumably an isolated
part of the program, good practice dictates making it a
separate function. Here is one way:
main( ) {
int hist[129]; /* 128 legal chars + 1 illegal group */
...
count(hist, 128); /* count the letters into hist */
printf( ... ); /* comments look like this; use them */
... /* anywhere blanks, tabs or newlines could appear */
}
count(buf, size)
int size, buf[ ]; {
int i, c;
for( i=0; i<=size; i++ )
buf[i] = 0; /* set buf to zero */
while( (c=getchar( )) != '\0' ) { /* read til eof */
if( c > size || c < 0 )
c = size; /* fix illegal input */
buf[c]++;
}
return;
}
We have already seen many examples of calling a function, so
let us concentrate on how to define one. Since count has
two arguments, we need to declare them, as shown, giving
their types, and in the case of buf, the fact that it is an
array. The declarations of arguments go between the argu-
ment list and the opening `{'. There is no need to specify
the size of the array buf, for it is defined outside of
count.
The return statement simply says to go back to the cal-
ling routine. In fact, we could have omitted it, since a
return is implied at the end of a function.
What if we wanted count to return a value, say the
number of characters read? The return statement allows for
this too:
int i, c, nchar;
nchar = 0;
...
while( (c=getchar( )) != '\0' ) {
if( c > size || c < 0 )
c = size;
buf[c]++;
nchar++;
}
return(nchar);
Any expression can appear within the parentheses. Here is a
function to compute the minimum of two integers:
min(a, b)
int a, b; {
return( a < b ? a : b );
}
To copy a character array, we could write the function
strcopy(s1, s2) /* copies s1 to s2 */
char s1[ ], s2[ ]; {
int i;
for( i = 0; (s2[i] = s1[i]) != '\0'; i++ );
}
As is often the case, all the work is done by the assignment
statement embedded in the test part of the for. Again, the
declarations of the arguments s1 and s2 omit the sizes,
because they don't matter to strcopy. (In the section on
pointers, we will see a more efficient way to do a string
copy.)
There is a subtlety in function usage which can trap
the unsuspecting Fortran programmer. Simple variables (not
arrays) are passed in C by ``call by value'', which means
that the called function is given a copy of its arguments,
and doesn't know their addresses. This makes it impossible
to change the value of one of the actual input arguments.
There are two ways out of this dilemma. One is to make
special arrangements to pass to the function the address of
a variable instead of its value. The other is to make the
variable a global or external variable, which is known to
each function by its name. We will discuss both possibili-
ties in the next few sections.
If we say
f( ) {
int x;
...
}
g( ) {
int x;
...
}
each x is LOCAL to its own routine _ the x in f is unrelated
to the x in g. (Local variables are also called
``automatic''.) Furthermore each local variable in a routine
appears only when the function is called, and _d_i_s_a_p_p_e_a_r_s
when the function is exited. Local variables have no memory
from one call to the next and must be explicitly initialized
upon each
Page : << Previous 5 Next >>