目录
[1.1 函数指针的概念和应用](#1.1 函数指针的概念和应用)
[1.2 赋值与内存模型](#1.2 赋值与内存模型)
[1.3 调用方式与注意事项](#1.3 调用方式与注意事项)
[2.1 函数指针的定义和访问](#2.1 函数指针的定义和访问)
[2.2 动态调度:用户输入驱动函数执行](#2.2 动态调度:用户输入驱动函数执行)
[2.3 函数指针数组进阶应用](#2.3 函数指针数组进阶应用)
[2.4 函数作为参数的高阶抽象](#2.4 函数作为参数的高阶抽象)
[3.1 指针函数vs函数指针](#3.1 指针函数vs函数指针)
[3.2 指针函数应用](#3.2 指针函数应用)
[3.3 回调函数机制解析](#3.3 回调函数机制解析)
[3.4 消息循环](#3.4 消息循环)
函数指针是C语言中指向函数的指针变量,其本质是存储函数入口地址的指针。与普通指针不同,函数指针指向的是代码段中的可执行指令,而非数据存储区域。
1.1 函数指针的概念和应用
·核心概念
函数指针的类型由函数的返回值类型和参数列表共同决定。
例如:
input (*ptr)(int, char)
表示ptr是一个指向返回值为int、参数为 (int, char) 的函数的指针。
·应用
- 动态函数调用:根据运行时条件选择执行不同函数
- 回调机制:实现框架与业务代码的解耦
- 算法通用化:如自定义排序函数的比较逻辑
1.2 赋值与内存模型
- 示例
cpp
int add(int a, int b){ return a+b; } //两数之和
int sub(int a, int b){ return a-b; } //两数之差
- 函数指针赋值
cpp
//函数指针赋值
int (*ptr)(int, int) = add; //直接赋值函数名(隐式取地址)
ptr = ⊂ //显式取地址(等价于sub)
·内存本质:函数指针存储的是函数在内存中的起始地址(add与&add等价),该地址指向函数的机器码起始位置。
1.3 调用方式与注意事项
cpp
int result1 = ptr(3,5);
int result2 = (*ptr)(3,5);
⚠️注意事项
- 调用前必须确保指针已正确指向有效函数
- 参数类型、个数与指针声明完全匹配
- 避免指向局部函数或已释放的函数(如动态链接库卸载后的函数)
二、函数指针的使用
2.1 函数指针的定义和访问
cpp
//使用typedef简化声明
typedef int (*Func)(int, int);
Func ad = add; //定义简洁
int res = ad(10,20);
·类型别名优势:
- 代码可读性提高,明确指针用途
- 批量修改函数签名时只需要修改一处
2.2 动态调度:用户输入驱动函数执行
·头文件
cpp
#include <stdio.h>
·定义add和sub
cpp
int add(int a,int b) { return a+b; }
int sub(int a,int b) { return a-b; }
·主函数
cpp
int main() {
int x,y,choice;
typedef int (*Func)(int, int);
Func ads[] = {add, sub};
printf("选择(0:加,1:减): ");
scanf("%d",&choice);
printf("输入两个数: ");
scanf("%d%d",&x,&y);
int result = ads[choice](x,y); // 动态调用
printf("结果: %d\n",result);
return 0;
}
⬇️


执行逻辑:
通过数组下标映射用户输入,实现低成本的多函数调度方案
2.3 函数指针数组进阶应用
cpp
typedef int(*MathFunc)(int, int);
MathFunc funcs[] = {
add, // 0:加法
sub, // 1:减法
mul, // 2:乘法
div // 3:除法
};
//动态调用示例
int result = funs[choice](a,b);
· 优势场景
当需要管理大量函数时,数组索引可提供O(1) 时间复杂度的快速访问。
2.4 函数作为参数的高阶抽象
cpp
// 通用排序函数(接收比较函数作为参数)
void sort(int arr[], int len, int (*cmp)(int, int)) {
// 冒泡排序实现
for (int i=0; i<len-1; i++) {
for (int j=0; j<len-i-1; j++) {
if (cmp(arr[j], arr[j+1]) > 0) {
// 交换元素
}
}
}
}
// 升序比较函数
int cmp_asc(int a, int b) { return a - b; }
// 降序比较函数
int cmp_desc(int a, int b) { return b - a; }
// 使用示例
sort(arr, 10, cmp_asc); // 升序排序
sort(arr, 10, cmp_desc); // 降序排序
三、回调函数
3.1 指针函数vs函数指针
|----------|--------------------|-----------|
| 类型 | 定义语法 | 本质 |
| 指针函数 | int* func(int a) | 返回指针的函数 |
| 函数指针 | int(*func)(int a) | 指向函数的指针变量 |
3.2 指针函数应用
cpp
// 返回动态分配数组的指针函数
int* create_arr(int size) {
int* arr = (int*)malloc(size * sizeof(int));
// 初始化数组
return arr;
}
3.3 回调函数机制解析
回调函数是通过函数指针实现的一种双向通信机制:
- 调用方定义函数原型并预留指针函数
- 被调用方(如库函数)在特定事件发生时调用该指针
cpp
// 模拟操作系统定时器回调
typedef void (*Callback)(int data);
void set_timer(int ms, Callback cb) {
// 模拟定时器逻辑
while (ms > 0) { /* 延时 */ }
cb(42); // 时间到达时触发回调
}
// 用户自定义回调函数
void on_timer(int data) {
printf("定时器触发,数据: %d\n", data);
}
// 使用示例
set_timer(1000, on_timer); // 注册回调函数
3.4 消息循环
cpp
// 简化的GUI消息循环
typedef void (*MsgHandler)(int msg, void* data);
void message_loop(MsgHandler handler) {
while (1) {
int msg = get_next_message(); // 获取消息
void* data = get_message_data(msg);
handler(msg, data); // 分发消息到回调函数
}
}
// 用户注册消息处理函数
void handle_msg(int msg, void* data) {
switch (msg) {
case WM_CLICK: process_click(data); break;
case WM_KEYDOWN: process_keypress(data); break;
}
}
// 启动消息循环
message_loop(handle_msg);