Function Pointers
As with Scheme, C allows variables to refer to functions, and functions can be passed as parameters. However, since C requires the type of each variable or parameter be declared, variables that may refer to functions must indicate the function's signature (number and type of parameters, return type).
In this unit, we begin with a reading from your textbook, supplemented by a demonstration of passing functions as parameters to procedures, just as we did in Scheme.
Textbook reading
- King: Section 17.7, pages 439-445
Function Pointers and Arrays
The remainder of this reading presents a simple example that illustrates the use of functions as parameters.
Initial Example
Suppose you are asked to write a program to compute a circle's circumference and area for radii between 0 and 9. The desired output might be:
radius circumference area 0.0000 0.0000 0.0000 1.0000 6.2832 3.1416 2.0000 12.5664 12.5664 3.0000 18.8496 28.2743 4.0000 25.1327 50.2655 5.0000 31.4159 78.5398 6.0000 37.6991 113.0973 7.0000 43.9823 153.9380 8.0000 50.2655 201.0619 9.0000 56.5487 254.4690
One simple approach for writing this type of program might utilize these features:
- Separate functions are defined for the circumference and the area of a circle.
-
The first line of the
mainprogram prints a header. -
A main loop iterates through the desired
radiusvalues. -
The loop itself contains three
printfstates, one for each value to be printed on a given line.
The resulting C program follows:
/* program to compute a circle's circumference and area */
#include
#include /* Provides constant M_PI */
/* calculate the circumference of a circle given its radius */
double
circumference (double radius)
{
return 2 * M_PI * radius;
} // circum
/* calculate the area of a circle given its radius */
double
area (double radius)
{
return M_PI * radius * radius;
} // area
/* main processing */
int
main (void)
{
printf (" radius circumference area\n");
double radius;
for (radius = 0; radius < 10; radius++)
{
printf ("%12.4lf", radius);
printf ("%12.4lf", circumference(radius));
printf ("%12.4lf", area(radius));
printf ("\n");
}
return 0;
} // main
Function Parameters
The above C program works fine and likely is completely satisfactory for the simple problem given. However, several elements in the program contain some common elements. For example,
-
The first three
printfstatements all use the same format string, and they each print just one value. -
The second and third
printfstatements call a function, the function requires one parameter, andradiusis used in the function call. -
Arguably, the first
printfstatement also has this format, where the function called is the identify functionx = iden(x)
Although these common elements are hardly earth shaking, it can be helpful to take advantage of such common elements in more complicated programs.
Printing Function
In exploiting the similarities in the printf statements,
we might write a function that takes a radius and a function as
parameters and then performs the required printing. The following
code is an example:
/* printing function */
void
myPrint (double x, double func (double))
{
printf ("%12.4lf", func(x));
} // myPrint
This function has two formal parameters, the number x
and a function f. Further, f is identified
as a function that will utilize one double value as an
input parameter, and f will return a double
when it completes execution.
The function myPrint utilizes the function
f when it performs its printing.
Full Program
The following program replaces the printf statements in
the main loop by calls to myPrint.
Note that myPrint is also used for printing the value
of radius by using an identify function. The code
observes, however, that a simple printf
for radius could be used as a reasonable alternative.
/* program to compute a circle's circumference and area example using function
with a function parameter */
#include
#include
/* identity function (return the value given) */
double
identity (double radius)
{
return radius;
} // identity
/* calculate the circumference of a circle given its radius */
double
circumference (double radius)
{
return 2 * M_PI * radius;
} // circum
/* calculate the area of a circle given its radius */
double
area (double radius)
{
return M_PI * radius * radius;
} // area
/* print the value of a given function at the given value */
void
myPrint (double x, double func (double))
{
printf ("%12.4lf", func (x));
} // myPrint
/* main processing */
int
main (void)
{
printf (" radius circumference area\n");
double radius;
for (radius = 0; radius < 10; radius++)
{
myPrint (radius, identity); /* could also be printf ("%12.4lf", radius); */
myPrint (radius, circumference);
myPrint (radius, area);
printf ("\n");
}
return 0;
} // main
