4.4 函数指针与回调函数

本篇学习函数指针声明、调用与回调函数的基本用法,并能把行为作为参数传给另一个函数。

函数指针与回调函数

概念说明

函数指针是“指向函数的指针”,它保存的是函数入口地址。 有了函数指针,我们就可以把一个函数当作参数传给另一个函数,这种写法通常叫回调函数。

回调并不神秘,本质上就是“把某个动作延后到别处执行”。 排序、事件处理、状态机、策略选择等场景里都很常见。

初学者最容易卡住的点不是“回调思想”,而是声明语法。 这时可以先抓住括号:int (*op)(int, int) 中,op 是一个指针,它指向“参数为两个 int、返回 int”的函数。

语法/规则

  1. 函数指针声明要写清返回类型和参数列表,例如 int (*op)(int, int);
  2. 函数名在很多表达式里会退化为函数地址,因此传参时可以直接写函数名。
  3. 通过函数指针调用函数时,op(1, 2)(*op)(1, 2) 都常见。
  4. 回调函数的签名必须和函数指针类型匹配。
  5. 如果声明太难读,可以配合 typedef 给函数指针取别名,提升可读性。
  6. 函数指针和普通数据指针是不同概念,不要混用。
  7. 回调通常只负责“做什么”,调用时机和参数准备则由外层函数控制。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int sub(int a, int b) {
    return a - b;
}

int apply(int (*op)(int, int), int a, int b) {
    return op(a, b);
}

int main(void) {
    printf("add = %d\n", apply(add, 3, 4));
    printf("sub = %d\n", apply(sub, 3, 4));
    return 0;
}

输出结果:

1
2
add = 7
sub = -1

常见错误

  1. 忘了在声明里给 *op 加括号,导致类型含义完全变掉。
  2. 把函数返回值传进去,而不是把函数本身传进去。
  3. 回调参数签名不一致,编译器可能警告,运行时也可能出现更隐蔽的问题。
  4. 一看到函数指针就害怕,结果错过了很多“把行为参数化”的简洁写法。
  5. 在回调设计里把职责边界写乱,导致外层函数和回调函数都在做同一件事。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字