Function Pointers, Parameters, and Arrays
Working with Functions
As with several programming languages, 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).
Reading Outline
This reading presents an extended example that illustrates:
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
Program circle-cirum-area-1.c illustrates one simple approach for writing this type of program.
/* program to compute a circle's circumference and area */ #include <stdio.h> const double pi = 3.1415926535; /* circumference function */ double circum (double radius) { return 2 * pi * radius; } /* area function */ double area (double radius) { return pi * radius * radius; } int main () { printf (" radius circumference area\n"); double radius; for (radius = 0; radius < 10; radius++) { printf ("%12.4lf", radius); printf ("%12.4lf", circum(radius)); printf ("%12.4lf", area(radius)); printf ("\n"); } return 0; }
The simple program circle-cirum-area-1.c includes these features:
-
Separate functions are defined for the circumference and the area of a circle.
-
The first line of the main program prints a header.
-
A main loop iterates through the desired radius values.
-
The loop itself contains three printf states, one for each value to be printed on a given line.
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 printf statements all use the same format string, and they each print just one value.
-
The second and third printf statements call a function, the function requires one parameter, and radius is used in the function call.
-
Arguably, the first printf statement also has this format, where the function called is the identify function x = 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 */ double myPrint (double x, double f (double)) { printf ("%12.4lf", f(x)); }
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 circle-cirum-area-2.c replaces the printf statements in the main loop by calls to myPrint.
/* program to compute a circle's circumference and area example using function with a function parameter */ #include <stdio.h> const double pi = 3.1415926535; /* identity function */ double iden (double radius) { return radius; } /* circumference function */ double circum (double radius) { return 2 * pi * radius; } /* area function */ double area (double radius) { return pi * radius * radius; } /* printing function */ void myPrint (double x, double f (double)) { printf ("%12.4lf", f(x)); } int main () { printf (" radius circumference area\n"); double radius; for (radius = 0; radius < 10; radius++) { myPrint (radius, iden); /* could also be printf ("%12.4lf", radius); */ myPrint (radius, circum); myPrint (radius, area); printf ("\n"); } return 0; }
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.
Arrays of Functions
As noted earlier in this lab, functions as parameters provide one mechanism to take advantage of common elements within an algorithm. A second approach involves utilizing an array of functions.
Declaration
Already, we have observed that the main loop in our example utilizes the same printf statement — with different functions being called. This suggests that we might declare an array of the relevant functions:
double (*funcarr[3]) (double)= {iden, circum, area};
Let's unpack this syntax:
-
We can declare a simple variable as a pointer to a function with the statement:
double (*f) (double)
This states that f will refer to a function that has one parameter (a double) and it will return a double. (The * means that f will be a function pointer — a reference to a function.)
-
With this declaration, f can be assigned a function:
f = area;
so the statement
printf ("%5.2", f(3.5));
will cause the area function to be called, executed with the value 3.5, and used as the value to be printed.
-
As with many C declarations, a variable can be defined and initialized in a single statement. The following declaration initializes f as a reference to the area function.
double (*f) (double) = area;
-
Arrays are declared by placing [] within the declaration:
double (*funcarr[3]) (double);
Here funcarr is declared as an array of 3 function pointers.
-
Arrays can be initialized by placing desired values within braces
{ }:
double (*funcarr[3]) (double)= {iden, circum, area};
-
With this declaration, we can refer to the circum function as
funcarr[1]
and we can call this function with the parameter 3.5 by writing
funcarr[1] (3.5)
Full Program
The following program circle-cirum-area-3.c uses this declaration of funcarr in the main loop by iterating through the three functions of interest for printing.
/* program to compute a circle's circumference and area example using an array of functions */ # include <stdio.h> const double pi = 3.1415926535; /* identity function */ double iden (double radius) { return radius; } /* circumference function */ double circum (double radius) { return 2 * pi * radius; } /* area function */ double area (double radius) { return pi * radius * radius; } int main () { double (*funcarr[3]) (double) = {iden, circum, area}; printf (" radius circumference area\n"); double radius; for (radius = 0; radius < 10; radius++) { int i; for (i = 0; i < 3; i++) { printf ("%12.4lf", funcarr[i](radius)); } printf ("\n"); } return 0; }
created 21 July 2012 by Henry M. Walker revised 22 July 2012 by Henry M. Walker URL updated 22 September 2013 by Henry M. Walker reformatted with minor editing 12 August 2016 by Henry M. Walker |
![]() ![]() |
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu. |