1. | Welcome | ToC | FAQ | Resources | Courses | Projects | Mail Lists | Members | Misc |
2. | Fundamentals | Languages | Tools | Net | Core | Advanced |
3. | EoC | Java |
4. | Lessons |
5. | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |


Essence of C
6 - FUNCTIONS

General Form, Scope Rules, Arguments, Calling Functions With Arrays, Returning Values and Pointers, Recursion

The General Form of a Function

The general form of a function is:

    type_specifier function_name(parameter list)
    {
     body of function;
    }

where type_specifier specifies the type of value that the function's return statement returns and the parameter list is a comma-separated list of variable names and types which receive the values of the arguments passed by the call to the function.

Scope Rules of Functions

The scope rules of a language are the rules which govern whether a piece of code knows about, or has access to, another piece of code or data.

In C, a function's code cannot be accessed other than by a call to that function. The code and data defined within a function cannot interact with the code or data defined in another function because two functions have a different scope.

Function Arguments

If a function is to use arguments, variables (known as formal parameters) must be declared to accept the values of the arguments. The type of the arguments used to call the function must be compatible with the type of its parameters. (The use of function prototypes can help catch errors in this regard.)

Assignments may be made to formal parameters, and those parameters may be used in any valid C expression. Essentially, parameters are, and may be used like, local variables.

Functions may be passed arguments by call-by-value or call-by-reference.


Call-by-Value

The call-by-value method copies the value of an argument into the formal parameter of the function. Therefore, changes made by the function to the parameters have no effect on the variables used to call it.


Call-by-Reference

The call-by-reference method copies the address of an argument into the formal parameter. Inside the function, this address is used to access the argument used in the call. In this way, changes made to the parameter affect the variable used in the call to the function.

Calls-by-reference are achieved by passing a pointer as the argument. Of course, in this case, the parameters must be declared as pointer types. The following demonstrates this:

 

    void swap(int *x, int *y); // function prototype

    void main(void)
    {
      int x,y;

      x = 10;
      y = 20;
      swap(&x,&y) // addresses passed
    }

    void swap(int *x, int *y)
    {
      int temp;

      temp = *x;
      *x = *y;
      *y = temp;
    }


Calling Functions With Arrays

Generally, the C convention is the call-by-value. An exception is where arrays are passed as arguments.

When an array is passed to a function, only the address is passed, not the entire array. When a function is called with just the array name, a pointer to the array is passed. (In C, an array name without an index is a pointer to the first element.) This means that the parameter declaration must be of a compatible pointer type. There are three ways to declare a parameter which is to receive an array pointer:

On the other hand, an array element used as an argument is treated like any other simple variable, as shown in this code fragment:

 

    display(t[a]);
    ...
    void display(int num)
    {
      printf("%d", num;
    }


argc and argv - Arguments to main()

Information may be passed into the program from the command line using the two special built-in arguments argc and argv. The former holds the number of arguments and the latter is a pointer to an array of character pointers. The value in argc is always at least 1 because the program name counts as the first argument. An example of usage is as follows:

 

    void main(int argc, char *argv[]) {
    if(argc != 2)
    {
      printf("You forgot to type your name\n");
      exit(1);
    }

    printf("Hello %s", argv[1]);
    }

The names argc and argv are traditional but arbitrary, and may be changed to anything the programmer prefers.

The return Statement

return causes an immediate exit from a function. It may also be used to return a value. All functions, except those of type void, return a value. (If no return statement is present, most compilers will cause a 0 to be returned.)

Returning Values

As long as a function is not declared as void, it may be used as an operand in any C expression, e.g.:

 

    x = power(y);
    if(max(x,y) > 100)
      printf("greater");
    for(ch = getchar();isdigit(ch); );

However, a function cannot be the target of an assignment.

The purpose of most functions is to either perform a computation and return a value, manipulate information and return a success-or-failure (true or false) value, or perform a strictly procedural routine which produces no value (eg, the exit() function).

Some functions which do not produce an interesting result return something anyway. For example, printf() returns the number of characters written, although it would be unusual to find a program which used this value. In other words, the returned value does not have to be used if it serves no purpose.

Functions That Return Non-Integer Values

Functions may be declared to return any valid C data type. If the return type is not specified, it automatically defaults to type int. If a program calls a function which, due to a programming error, returns a type different from that specified by the function, and if that call is made before the function is declared, the compiler will generate the wrong code for the function call. To prevent this, a special form of declaration statement is used at the top of the program to tell the compiler what value that function is returning.

The traditional method for such declaration has now been replaced by the ANSI C method of the function prototype. The traditional method takes the form:

 

    type_specifier function_name();

The ANSI function prototype, on the other hand, takes the form:

 

    type function_name(type param_name1, type param_name2, ...,);

the difference being that the ANSI form specifies the type of the arguments expected to be received by the function. This enables the compiler to identify any type mismatch between the calling arguments and the formal parameters.

void must be used inside the parentheses of function prototypes for functions which receive no arguments.

Returning Pointers

Functions that return pointers are handled just like any other type of function, e.g.:

 

    char * match(char c, char *s)
    {
       while(c != *s && *s)
         s++;
       return(s);
    }

Functions of type void

Declaring a function of type void prevents its use in expressions. A void function's prototype must be declared before it is called, otherwise the compiler will assume that it returns an integer and declare a type mismatch.

What does main() Return?

The ANSI standard states that main() returns an integer to the calling process (generally the operating system). Returning a value from main() is the same as calling exit() with the same value. main() may be declared as void if it does not return a value.

Recursion

C supports recursion. In other words, in C, a function may call itself.

Parameter Lists of Variable Length and Type

In C, a function may be specified as having a varying number of parameters. In this case the parameter declaration must be ended with three periods, as in:

 

    function(int a, int b, ...);

This form must also be used in the function's prototype.

There must always be at least one actual argument.

Efficiency

Where execution speed is critical, in-line code should be used instead of the relevant function. In-line code is simply the function's statements used without a call to the function. In-line code is faster because the call itself takes time to execute and because the passed arguments must be placed on the stack, which also takes time.

Libraries and Files

Functions may be left in the main program or they may be placed in libraries or separate files. Technically, a library differs from a separately compiled file of functions in that, when a routine from a library is linked with the main program, only the functions used by that program are linked. Most C compilers include instructions for creating a library.

Prior Chapter · Index · Next Chapter


Copyright © 1996, 1997, 1998. Last Update to This Page: 1998/10/24
This Page Maintained by: radar pangaean * * * Original Author: K.J.Bricknell
The MOST web site is built and maintained by the voluntary efforts/donations of our members.