C Subprograms

In C, all subprograms are functions. Recall that C does distinguish between assignment statements and subroutine calls as Fortran does. Any expression followed by a semicolon is a valid statement in C.

Following the minimalist philosophy, C also has no intrinsic (built-in) functions. Commonly used functions such as sin(), sqrt(), etc. are provided by libraries, archives of functions written in C (or any other compiled language).

The basic syntax of a C function definition is as follows:

return-type    function-name(argument variable definitions)

{
    local variable definitions
    
    body
    
    return [value];
}
        

The return type can be any basic data type described in Table 17.1, “C Data Types” or a pointer (discussed in Chapter 23, Memory Addresses and Pointers).

It is also possible to define a function that does not return a value by giving it a return type of void. However, most C functions do return a value of some sort. Functions that do not compute a result such as a square root generally return a status value to indicate whether the function completed successfully.

Since any expression followed by a semicolon is a valid statement in C, it is acceptable (although not a good idea) to ignore the return value of some functions.

For example, the library function printf() returns the number of characters printed, or a negative value if an error occurred. We often ignore the return value:

printf("The square of %f is %f\n", n, n * n);
        

However, errors can occur on output due to a disk being full or a network connection being lost, so it's a good idea to check:

if ( printf("The square of %f is %f\n", n, n * n); < 0 )
{
    // printf() failed.  Handle the error as gracefully as possible.
}
        

The scanf() function returns the number of input items successfully read. It is important to check for success, since input errors are common.

if ( scanf("%d %d", &rows, &cols) != 2 )
{
    // scanf() failed.  Handle the error as gracefully as possible.
}
        

Note

Only functions that absolutely cannot fail should be defined with a void return type. All others should return a status value so that the caller can detect errors and take appropriate action.

Below is a sample C program showing a definition of a power() function. In addition to the function definition, the program contains a prototype for the function above main(), which is explained in the section called “Type Matching”.

/***************************************************************************
 *  Description:
 *      Program to print a table of integer powers
 *  
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      See sysexits.h
 *
 *  History: 
 *  Date        Name        Modification
 *  2013-08-12  Jason Bacon Begin
 ***************************************************************************/

#include <stdio.h>
#include <sysexits.h>

// Prototypes
double  power(double base, int exponent);

int     main(int argc,char *argv[])

{
    // Variable definitions
    int exponent;
    
    // Statements
    puts("Powers of 2");
    for (exponent = 0; exponent <= 10; ++exponent)
        // Will not work with 2.0 instead of 2.0d0
        printf("2 ^ %d = %f\n", exponent, power(2.0, exponent));

    puts("Powers of 3");
    for (exponent = 0; exponent <= 10; ++exponent)
        // Will not work with 3.0 instead of 3.0d0
        printf("3 ^ %d = %f\n", exponent, power(3.0, exponent));

    return EX_OK;
}


/***************************************************************************
 *  Description:
 *      Compute base ** exponent for any non-negative integer exponent
 *  
 *  Arguments:
 *      base:       The real base of base ** exponent
 *      exponment:  The non-negative integer exponent
 *
 *  Returns:
 *      base ** exponent
 *
 *  History: 
 *  Date        Name        Modification
 *  2013-08-12  Jason Bacon Begin
 ***************************************************************************/

double  power(double base, int exponent)

{
    // Local variables
    double  p;
    
    // Compute n!
    p = 1.0;
    
    while ( exponent-- >= 1 )
        p *= base;
    return p;
}