一、函数指针做函数参数
1、使用函数指针间接调用函数
在上一篇博客 【C++】函数指针 ③ ( 函数指针语法 | 函数名直接调用函数 | 定义函数指针变量 | 使用 typedef 定义函数类型 | 使用 typedef 定义函数指针类型 ) 中 , 最后一个示例 , 使用 typedef 定义函数指针类型 如下 :
// int (int, int) 函数指针类型重命名为 pFun_add
// 该类型变量可以直接接收 函数名 ( 函数地址 )
typedef int (*pFun_add)(int, int);
通过该指针类型 , 可以 间接调用 add 函数 ;
// 定义函数指针类型变量
pFun_add pFun = add;
// 通过函数指针间接调用 add 函数
pFun(7, 8);
如果将 函数指针变量 pFun_add pFun
作为参数 , 传递给函数 , 在函数内部可以调用其它函数 , 调用的函数可以动态指定 ;
2、函数指针做参数
定义了 如下 函数指针类型 pFun_add , 其类型为 int (*)(int, int) , 该指针指向一个 类型为 int (int, int) 的 函数 ;
// int (int, int) 函数指针类型重命名为 pFun_add
// 该类型变量可以直接接收 函数名 ( 函数地址 )
typedef int (*pFun_add)(int, int);
定义函数 接收 pFun_add 类型的形参作为参数 , 该类型是 函数指针类型 , 也就是 函数接收一个 函数指针类型参数 , 在该函数中调用 函数指针 指向的 函数 ;
// 传入函数指针, 使用传入的函数进行计算
int caculate(pFun_add fun, int x, int y) {
printf("使用 fun 函数计算 x 和 y = %d\n", fun(x, y));
return fun(x, y);
}
定义 caculate 函数时 , 只定义了 在函数体内部 要调用 int (int, int) 类型的函数 , 具体是什么函数 , 需要在运行时 , 动态传入 ;
函数指针类型 的该用法 是框架的基础 , 将 函数执行逻辑 与 软件框架 进行解耦 ;
也就是 将 任务调用者 与 任务实现者 进行了隔离 , 解耦合 ;
下面的示例中 , 可以将 函数指针类型变量 pFun_add pFun = add
传入函数作为参数 , 也可以直接将 add
函数名 ( 函数地址 ) 作为 函数指针 参数 传递给函数 ;
// 定义函数指针类型变量
pFun_add pFun = add;
// 通过函数指针间接调用 add 函数
pFun(7, 8);
// 将 函数指针 作为参数传递到函数中
caculate(pFun, 9, 10);
// 可以直接将 函数名 ( 函数地址 ) 作为 函数指针 参数
// 传递给函数
caculate(add, 11, 12);
3、函数指针类型的本质
函数指针类型 本质 : 提前对任务 格式 进行约定 ;
- 函数参数类型 约定了 函数的 参与者 ;
- 函数返回值类型 约定了 函数的 执行结果 ;
只要 将 子任务 按照 上述 " 函数指针类型 " 的约定 , 开发出 符合要求 的 函数 , 就可以将其作为一个 子任务 传递到 其它函数中执行 ;
4、函数指针做参数意义
函数指针做参数意义 :
- 提高程序灵活性 : 通过使用函数指针作函数参数 , 这样可以 在 程序 运行时 动态地 设置 要调用的函数 , 提高了程序的灵活性 ;
- 作为回调函数 : 函数指针 可以作为 回调函数 ; 先将 函数指针变量 作为 实参 传递给 其它函数 , 在 接收函数指针 的函数内部 , 满足某种条件时直接调用该函数指针 指向的 函数 , 这样实现了回调 ;
- 解耦 任务调用 与 任务实现 : 厂商提供 任务实现 , 系统集成商 调用 厂商实现的任务 , 此时 系统集成商 只需要写好 软件框架 , 调用 厂商提供的 任务实现即可 ;
- 更好的代码组织 : C 语言 中模拟面向对象用法 ; 可以将特定的 函数指针类型 定义为 结构体 的一部分 , 并使用该 结构体 来传递具有特定行为的对象的地址 ; 该操作有助于更好地组织代码 , 使代码更易于理解和维护 ;
- 错误处理 : 使用函数指针 , 将错误处理函数作为参数传递给其他函数 , 在发生错误时立即调用适当的错误处理函数 , 无需返回到调用堆栈中的较高层次 ;
二、代码示例 - 函数指针做函数参数
代码示例 :
#include "iostream"
using namespace std;
// int (int, int) 函数指针类型重命名为 pFun_add
// 该类型变量可以直接接收 函数名 ( 函数地址 )
typedef int (*pFun_add)(int, int);
int add(int x, int y) {
printf("x + y = %d\n", x + y);
return x + y;
}
// 传入函数指针, 使用传入的函数进行计算
int caculate(pFun_add fun, int x, int y) {
printf("使用 fun 函数计算 x 和 y = %d\n", fun(x, y));
return fun(x, y);
}
int main() {
// 定义函数指针类型变量
pFun_add pFun = add;
// 通过函数指针间接调用 add 函数
pFun(7, 8);
// 将 函数指针 作为参数传递到函数中
caculate(pFun, 9, 10);
// 可以直接将 函数名 ( 函数地址 ) 作为 函数指针 参数
// 传递给函数
caculate(add, 11, 12);
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
}
执行结果 :
x + y = 15
x + y = 19
使用 fun 函数计算 x 和 y = 19
x + y = 19
x + y = 23
使用 fun 函数计算 x 和 y = 23
x + y = 23
Press any key to continue . . .