Function Pointers
A function pointer is a pointer that stores the address of a function. You use it to switch which function to call at runtime, or to implement callbacks by passing a function as an argument.
Syntax
// Declare a function pointer type. // return_type (*pointer_name)(parameter_type, ...); int (*fp)(int, int); // Assign a function's address (the function name itself is the address). fp = function_name; // Call a function through the function pointer. fp(arg1, arg2); (*fp)(arg1, arg2); // Explicit dereference — works the same way. // Using typedef to give a function pointer type a readable name. typedef return_type (*TypeName)(parameter_type, ...); TypeName variable_name = function_name;
Uses of Function Pointers
| Use | Description |
|---|---|
| Callbacks | Inject part of the logic from the caller. Commonly used in sorting, filtering, and event handling. |
| Dispatch table | Create an array of function pointers and switch which function to call by index. Can serve as an alternative to switch statements. |
| Strategy pattern | Swap out algorithms via function pointers to give structs different behaviors. |
| qsort / bsearch | These standard library functions accept a comparison function as a function pointer to sort or search data of any type. |
Sample Code
#include <stdio.h>
#include <stdlib.h>
// Define the functions to operate on.
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
// A callback function that takes a function pointer as an argument.
void apply(int x, int y, int (*op)(int, int), const char *name) {
printf("%s(%d, %d) = %d\n", name, x, y, op(x, y));
}
// Use typedef for readability.
typedef int (*BinaryOp)(int, int);
// Comparison function for qsort (ascending order).
int compare_asc(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}
// Comparison function for qsort (descending order).
int compare_desc(const void *a, const void *b) {
return (*(int *)b - *(int *)a);
}
int main(void) {
// Assign a function to a function pointer and call it.
int (*fp)(int, int) = add;
printf("add(3, 5) = %d\n", fp(3, 5)); // Prints: add(3, 5) = 8
fp = sub;
printf("sub(10, 3) = %d\n", fp(10, 3)); // Prints: sub(10, 3) = 7
// Pass functions as callbacks.
apply(6, 2, add, "add"); // Prints: add(6, 2) = 8
apply(6, 2, sub, "sub"); // Prints: sub(6, 2) = 4
apply(6, 2, mul, "mul"); // Prints: mul(6, 2) = 12
// Dispatch table (array of function pointers).
BinaryOp ops[] = {add, sub, mul};
const char *names[] = {"add", "sub", "mul"};
for (int i = 0; i < 3; i++) {
printf("%s(10, 4) = %d\n", names[i], ops[i](10, 4));
}
// Use function pointers with qsort.
int arr[] = {5, 1, 4, 2, 3};
qsort(arr, 5, sizeof(int), compare_asc);
printf("Ascending: ");
for (int i = 0; i < 5; i++) printf("%d ", arr[i]); // Prints: 1 2 3 4 5
printf("\n");
qsort(arr, 5, sizeof(int), compare_desc);
printf("Descending: ");
for (int i = 0; i < 5; i++) printf("%d ", arr[i]); // Prints: 5 4 3 2 1
printf("\n");
return 0;
}
Notes
Function pointers are how C implements higher-order functions — the ability to pass functions as arguments or return values. The standard library functions qsort() and bsearch() accept a comparison function via a function pointer, which allows them to sort or search data of any type generically.
Using typedef to give a function pointer type a meaningful name greatly improves code readability. Parentheses placement in function pointer declarations is critical: int *fp(int) declares a function that returns int *, while int (*fp)(int) declares a pointer to a function — they mean completely different things.
Embedding function pointers in structs enables object-oriented-style design in C. For more on structs, see struct. For type aliases, see typedef.
If you find any errors or copyright issues, please contact us.