Topic : Programming In C
Author : Brian Kernighan
Page : << Previous 5  Next >>
Go to page :


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;



14. Functions; Comments


     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.

15. Local and External Variables


     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 >>