A function’s name decays to its address. Storing that in a function pointer lets you pass behaviour as data — callbacks, dispatch tables, plug-in strategies, qsort comparators.
Syntax
#include <stdio.h>
int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
int main(void) {
int (*op)(int, int) = add; /* pointer to function taking (int,int) returning int */
printf("%d\n", op(3, 4));
op = &mul; /* & is optional */
printf("%d\n", (*op)(3, 4)); /* explicit * is optional too */
return 0;
}7
12Callbacks: qsort
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp_int_asc(const void *a, const void *b) {
int x = *(const int *)a, y = *(const int *)b;
return (x > y) - (x < y); /* avoids overflow of x - y */
}
int cmp_str(const void *a, const void *b) {
return strcmp(*(const char *const *)a, *(const char *const *)b);
}
int main(void) {
int nums[] = {42, -7, 19, 0, 3};
qsort(nums, 5, sizeof nums[0], cmp_int_asc);
for (int i = 0; i < 5; i++) printf("%d ", nums[i]);
printf("\n");
const char *words[] = {"pear", "apple", "fig"};
qsort(words, 3, sizeof words[0], cmp_str);
printf("%s %s %s\n", words[0], words[1], words[2]);
int key = 19;
int *hit = bsearch(&key, nums, 5, sizeof nums[0], cmp_int_asc);
printf("19 at index %td\n", hit - nums);
return 0;
}-7 0 3 19 42
apple fig pear
19 at index 3Your own higher-order function
#include <stdio.h>
typedef int (*transform_fn)(int);
int square(int x) { return x * x; }
int negate(int x) { return -x; }
void map(int *a, int n, transform_fn f) {
for (int i = 0; i < n; i++) a[i] = f(a[i]);
}
int main(void) {
int v[] = {1, 2, 3};
map(v, 3, square);
map(v, 3, negate);
printf("%d %d %d\n", v[0], v[1], v[2]);
return 0;
}-1 -4 -9Dispatch tables
#include <stdio.h>
double add(double a, double b) { return a + b; }
double sub(double a, double b) { return a - b; }
double mul(double a, double b) { return a * b; }
double dvd(double a, double b) { return a / b; }
int main(void) {
struct { char sym; double (*fn)(double, double); } ops[] = {
{'+', add}, {'-', sub}, {'*', mul}, {'/', dvd},
};
for (int i = 0; i < 4; i++)
printf("8 %c 2 = %g\n", ops[i].sym, ops[i].fn(8, 2));
return 0;
}8 + 2 = 10
8 - 2 = 6
8 * 2 = 16
8 / 2 = 4Callbacks with context
#include <stdio.h>
/* C has no closures: pass state through a void * "user data" pointer */
void for_each(const int *a, int n, void (*visit)(int, void *), void *ctx) {
for (int i = 0; i < n; i++) visit(a[i], ctx);
}
void accumulate(int x, void *ctx) { *(long *)ctx += x; }
int main(void) {
int a[] = {5, 10, 20};
long total = 0;
for_each(a, 3, accumulate, &total);
printf("total = %ld\n", total);
return 0;
}total = 35How do you declare a function that returns a function pointer?
What are function pointers used for in real systems?