Function Definitions
Each program we’ve presented has consisted of a function called main that called standard library functions to accomplish its tasks. We now consider how to write custom functions. Consider a program that uses a function square to calculate and print the squares of the integers from 1 to 10 . Place a blank line between function definitions to separate the functions and enhance program Readability
Example
/*creating and using a programmer-defined function */
#include <stdio.h>
int square(int y);
int main(void)
{
int x;
/* loop 10 times and calculate and output square of x each time */
for ( x = 1; x <= 10; x++ ) {
printf(“%d”, square( x ))
} /* end for */
printf( "\n" );
return 0; /* indicates successful termination */
} /* end main */
/* square function definition returns square of parameter */
int square( int y ) /* y is a copy of argument to function */
{
return y * y; /* returns square of y as an int */
} /* end function square */
Output
1 4 9 16 25 36 49 64 81 100
Function square is invoked or called in main within the printf statement
printf( "%d ", square( x ) ); /* function call */
Function square receives a copy of the value of x in the parameter y. Then square calculates y * y. The result is passed back to function printf in main where the square was invoked, and printf displays the result. This process is repeated 10 times using the for repetition statement. The definition of function square shows that square expects an integer parameter y. The keyword int preceding the function name indicates that square returns an integer result. The return statement in square passes the result of the calculation back to the calling function.
int square( int y ); /* function prototype */
is a function prototype. The int in parentheses informs the compiler that square expects to receive an integer value from the caller. The int to the left of the function name square informs the compiler that square returns an integer result to the caller. The compiler refers to the function prototype to check that calls to square contain the correct return type, the correct number of arguments, the correct argument types, and that the arguments are in the correct order.
The format of a function definition is
return-value-type function-name( parameter-list )
{
definitions
statements
}
The function-name is any valid identifier. The return-value-type is the data type of the result returned to the caller. The return-value-type void indicates that a function does not return a value. Together, the return-value-type, function-name and parameter-list are sometimes referred to as the function header.
Forgetting to return a value from a function that is supposed to return a value can lead to unexpected errors. The C standard states that the result of this omission is undefined. Returning a value from a function with a void return type is a compilation error. The parameter-list is a comma-separated list that specifies the parameters received by the function when it’s called. If a function does not receive any values, parameter-list is void. A type must be listed explicitly for each parameter.
Specifying function parameters of the same type as double x, y instead of double x, double y results in a compilation error. Placing a semicolon after the right parenthesis enclosing the parameter list of a function definition is a syntax error. Defining a parameter again as a local variable in a function is a compilation error. Although it’s not incorrect to do so, do not use the same names for a function’s arguments and the corresponding parameters in the function definition. This helps avoid ambiguity The definitions and statements within braces form the function body. The function body is also referred to as a block. Variables can be declared in any block, and blocks can be nested. A function cannot be defined inside another function. Defining a function inside another function is a syntax error.
Choosing meaningful function names and meaningful parameter names makes programs more readable and helps avoid excessive use of comments. A function should generally be no longer than one page. Better yet, functions should generally be no longer than half a page. Small functions promote software reusability.
Programs should be written as collections of small functions. This makes programs easier to write, debug, maintain and modify. A function requiring a large number of parameters may be performing too many tasks. Consider dividing the function into smaller functions that perform the separate tasks. The function header should fit on one line if possible. The function prototype, function header, and function calls should all agree on the number, type, and order of arguments and parameters, and in the type of return value.