1. 函数指针的概念
之前学过的指针可以指向变量、数组、字符串、结构体、指针,函数指针就是指向函数的指针。
声明函数指针的方法:"返回类型" (*"指针变量名") ("参数类型");
例如有一个返回值为int,参数为两个int类型的函数为int function(int num1, int num2);,可以定义指向这个函数的函数指针为:int (*myFunctionPointer) (int, int);
将原函数的地址赋给函数指针后,直接使用函数指针myFunctionPointer即可调用原函数。
赋地址时,取地址符&可以省略。
1 |
|
函数指针的用途为实现回调函数,函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。简单讲:回调函数是由别人的函数执行时调用你实现的函数,它允许将一个函数作为参数传递给另一个函数,这样,当特定事件发生的时候,可以触发调用传递的参数。
以下是来自知乎作者常溪玲的解说:
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
这种机制在事件驱动编程中非常常用。
2. 再探typedef
使用typedef可以为任意数据类型定义自定义的别名。
例如常用的uint32_t类型,在官方的定义中为typedef unsigned int uint32_t;。
甚至可以使用typedef为uint32_t类型自定义一个新的别名typedef uint32_t u32;,此时就可以使用别名类型u32直接声明变量,与原来的效果相同。
同样的,可以使用typedef为函数指针创建别名,例如typedef uint32_t (*func_ptr_t)(uint32_t, uint32_t);,定义后就可以直接使用别名func_ptr_t声明函数指针,代码更为简洁。
_t是type(类型)的缩写,是一个约定俗成的命名后缀,用于表示”这是一个自定义类型别名“,而非变量或函数。
1 |
|
3. 练习:指针函数的用途
当多个函数的返回值与参数都相同时,可以创建一个函数指针数组来存放所有的函数,直接使用函数指针数组的下标即可调用对应函数。
1 |
|
后续可以使用枚举为下标赋予有意义的名称,并实现数组的扩充。
4. 函数指针与callback回调函数的作用
回调函数是作为函数指针传递给另一个函数的函数,允许在后者中调用前者。
这种机制可以让程序在不同时间点或条件下,根据需要执行特定的功能。
例如写一个有遍历数组功能的函数,每次循环调用一次传入的函数指针,只要是返回值与参数类型相同的函数都可以传入,通过传入不同的函数,可以实现在遍历时执行不同的操作,相当于把遍历数组与具体要执行的操作模块化分开处理,提高代码的灵活性与可重用性。
1 |
|
5. 实际用途(函数指针与回调函数的妙用)
- 事件处理
- 异步编程
- 定时器函数
- 插件架构中的扩展点定义
- 排序算法中的自定义比较函数
- 多线程或并发编程中的线程启动函数
- 用户界面组件中的自定义渲染策略
- 网络请求处理中的协议解析器
- 状态机实现中的状态转换触发器
- 资源管理器中的资源释放策略回调
6. 事件处理框架(Event Handling Framework)
事件驱动的处理框架就是在某一个特定事件(Event)发生的时候执行特定的行动(Action)或功能(Function)。
例如组织一场派对,你是主人。
当有人敲门(一个事件)时,你要去开门(根据这个特定事件,你要做的行动);
当音乐停止,你要切换下一首……
7. 游戏架构事件设计:事件类型、事件处理函数、事件注册、事件分发机制
案例:一个游戏事件处理系统
- 定义事件类型和事件处理函数签名:首先定义游戏中可能发生的事件类型,以及处理这些事件的签名;
- 实现事件注册和分发机制:实现一个机制,允许为不同类型的事件注册处理函数,并且在相应的事件发生时调用这些函数;
- 定义事件处理函数:为游戏中的每一种事件类型定义具体的事件处理函数;
- 在游戏中使用事件处理系统:main中注册事件处理函数,并且模拟事件的发生来演示系统的工作流程。
代码实现:
1 |
|
注册事件本质上就是将某一个特定功能的函数的指针写入函数指针数组。
分发事件本质上就是在某一个条件下调用特定功能的函数。
本文链接: https://hanqingjiang.com/2026/03/20/20260320_C_functionPointer/
版权声明: 本作品采用 CC BY-NC-SA 4.0 进行许可。转载请注明出处!
