Previous Table of Contents Next


3.4.8. goto Statements

For fully general, unconstrained branching, C does provide the goto statement, although it is somewhat discouraged and rarely seen.

A label, which will presumably be the target of a goto, can be attached to any statement:

     statement1;
     statement2;
     if(condition)
             {
             statement3;
             }
     statement4;
end: statement5;

The syntax for a label is simply an identifier followed by a colon. The rules for label names are the same as for any identifiers. Labels have their own namespace, and they have a scope extending throughout the enclosing function. (For obvious reasons, labels never enjoy a restricted scope in inner blocks.)

The syntax of the goto statement is simply

goto label ;

Fleshing out the preceding example, we might have the following:

     statement1;
     statement2;
     if(condition)
             {
             statement3;
             goto end;
             }
     statement4;
end: statement5;

In this hypothetical example, if the condition is true, statement3 is executed, and then control immediately transfers to the end, executing only statement5, bypassing statement4. (In this case, of course, it would apparently also have been possible to have placed statement4 in an else clause of the if statement.)

goto statements are typically used, if at all, to effect breaks or continues out of nested loops, or to jump to the end of some segment of code (often to ensure that common cleanup actions—for example, statement5 in the example—are performed even when normal processing is skipped over due to some exceptional condition).

When a label is attached to a statement in an inner block (e.g., in an if or loop statement body), it is possible to jump into the loop. However, any initializers on variables declared within that block are not applied, so the practice of jumping into blocks is discouraged.

goto statements work only within a single function. A limited form of jumping between functions is provided by the library functions setjmp and longjmp (see section 3.10.8).

3.4.9. return Statements

The return statement terminates an invocation of a function, returning control to the function’s caller and optionally returning a value. The return statement is discussed further in the next section.

3.5. Functions

The function is the principal unit of modularity in a C program. Ideally, a function constitutes a “black box,” performing some operation that is useful to the rest of the program, but in such a way that the details of its operation need not be known to its callers. The only pieces of information a caller should need to know about a function are (1) its name, (2) the arguments it requires (if any), and (3) the type of its return value (if any).

Because C supports separate compilation, it is also possible to achieve another degree of modularity by grouping related functions and global variables into one source file, and arranging that those which are private to the module are visible (and accessible) only within that source file. (As described in section 3.2.6, the private variables and functions would be declared static.)

3.5.1. Defining Functions

The basic syntax for a function in C is

return-type function-name ( parameter-list )
{
           local-variable-declarations
            statements
}

The return-type declares the type of value to be returned by the function. The parameter-list declares the number and types of the arguments to be accepted by the function, as well as giving a name by which each is known within the function. The body of the function consists of declarations for any local variables, followed by the statements that actually do the work of the function. (The function body, including its enclosing braces, therefore matches the syntax for a block statement as described in section 3.4.)

As it happens, the italicized parts in the preceding skeleton, with the obvious exception of the function name, are all optional. If the return type is omitted, it defaults to int. If the parameter list is empty, it indicates a function that accepts no arguments at all. It is also possible for the body of the function to be empty, although this situation typically arises only during a program’s early development, when some functions are temporarily “stubbed out.”

When a function returns no value, it must be declared with the explicit return type void. When a function accepts no arguments, that fact can be explicitly indicated by placing the single keyword void in the parameter list (without any parameter names, of course). Modern practice is to use an explicit int for functions that return int and an explicit void in the parameter list for functions that accept no arguments.

Here is a complete example of a function definition:

int gcd(int a, int b)
{
       int t;
       while(b != 0)
               {
               t = a % b;
               a = b;
               b = t;
               }
  return a;
}

The function returns an int and accepts two int parameters, which it refers to by the identifiers a and b. The function declares one local variable, t. (Incidentally, what the function does is to compute the greatest common divisor of a and b, using Euclid’s classic algorithm.)


Previous Table of Contents Next