10 · 函数指针与回调

2026.09.27 · 🔴 难

核心认知:函数名就是它的地址

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);

关联

09-指针 · 21-命令行参数与排序算法 · 07-函数与作用域