10 · 函数指针与回调
核心认知:函数名就是它的地址
int add(int a, int b) { return a + b; }
int (*fp)(int, int) = add; // 声明一个函数指针并指向 add
int r = fp(3, 5); // 通过指针调用 → 8
int r2 = (*fp)(3, 5); // 等价写法
声明口诀:**返回类型 (指针名)(参数类型列表)*
int (*fp)(int, int); // fp 是指向「返回 int、两个 int 参数」的函数的指针
int *fp(int, int); // ⚠️ 这是「返回 int* 的普通函数」,括号不能少!
回调函数(函数指针的最大用途)
把函数当参数传进去,由被调用方在合适时机「回头调用」:
void process(int *arr, int n, int (*cb)(int)) {
for (int i = 0; i < n; i++)
arr[i] = cb(arr[i]); // 回调:具体做什么由调用者决定
}
int square(int x) { return x * x; }
int cube(int x) { return x * x * x; }
int a[] = {1, 2, 3};
process(a, 3, square); // → {1, 4, 9}
process(a, 3, cube); // → {1, 8, 27}
典型应用
qsort/bsearch的比较函数:qsort(arr, n, sizeof(int), cmp);- 事件回调、状态机、策略模式(C 里没有多态,靠函数指针模拟)。
⚡ Java 对比
Java 用接口 / Lambda / 方法引用实现回调;C 用函数指针。思想一样,写法更底层。
// C:传函数指针
qsort(a, n, sizeof(int), cmp);
// Java:传比较器
Arrays.sort(a, (x, y) -> x - y);