1Learning Outcomes¶
Understand function pointer syntax.
Declare and initialize function pointers, and call functions pointed to by function pointers.
🎥 Lecture Video
1.1Function Pointers¶
In a previous chapter we briefly mentioned function pointers.
int (*fn) (void *, void *) = &foo;
(*fn)(x, y);In the first line, fn is a function that accepts two void * pointers and returns an int. With this declaration, we set it to pointing to the function foo. The second line then calls the function with arguments x and y.
Function pointers allow us to define higher-order functions, such as map, filter, and generic sort.
Normally a pointer can only point to one type. In a future chapter we discuss the void * pointer, a generic pointer that can point to anything. In this course we will use the generic pointer sparingly to help avoid program bugs...and security issues...and other things... That being said, we will encounter generic pointers when working with memory management functions in the C standard library (stdlib).
2Example Code and Output¶
This program implements mutate_map, which maps a given function onto each element of an int array. Notably, mutate_map defines a function pointer parameter.
Example program map_func.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30#include <stdio.h> /* map function onto int array */ void mutate_map(int arr[], int n, int(*fp)(int)) { for (int i = 0; i < n; i++) arr[i] = (*fp)(arr[i]); } /* prints int arrays */ void print_array(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } int multiply2 (int x) { return 2 * x; } int multiply10(int x) { return 10 * x; } int main() { int arr[] = {3,1,4}, n = sizeof(arr)/sizeof(arr[0]); print_array(arr, n); mutate_map(arr, n, &multiply2); print_array(arr, n); mutate_map(arr, n, &multiply10); print_array(arr, n); return 0; }
This code multiplies the integer array arr by two, then multiplies arr again by ten, with two successive calls to mutate_map. The two mutate_map calls pass in different function pointers to multiply2 and multiply10, respectively.
Running the compiled map_func executable produces the following output:
$ ./map_func
3 1 4
6 2 8
60 20 80 More explanation
Line 4: Declare parameter
fp. Thefpparameter is a function pointer. It accepts oneintargument and returns anint.Lines 23, 26: Pass in function pointer argument. The function calls in Lines 23 and 26 pass in
multiply2andmultiply10, respectively as function pointer arguments. The address operator (&) is used for readability but is technically not needed.[1]Line 6: Call
fp. The syntax(*fp)(arr[i])calls the function pointed to byfpand passes in the argumentarr[i]. Like before, the dereference operator (*) is used for readability but is technically not needed for function pointers.[1]