回调函数的使用
回调函数的使用场景
送餐机器人:底盘移动到目标位置后,通知应用程序并执行相应的函数
智能音箱:网络状态改变时,通知应用程序执行相应的函数
传统的方法:
- 开放变量,让别人直接获取(不安全且代码杂乱)
- 通过getStatus()类似的函数定时获取,即封装一个函数来调用(效率低)
建议使用回调方法来实现。
回调函数应用实例代码
我们直接从代码层面开始说,不过你还需要了解一点函数指针的概率(函数指针可以理解为一个指向函数的指针,可以通过指针来调用函数,你可以理解为函数存放的位置就是对应的内存的一块地址,而你拿一个指针来指向这块地址的头部,并告知这块地址是一片函数区域)
下面我们就一段段讲解一下下面代码的执行流程
- 首先我们要从main函数看起,main函数只有两个方法,一个是addCallBackFunc(callBackFunc); 另一个是run();
- 我们按顺序先从addCallBackFunc(callBackFunc)来看,addCallBackFunc(void (*pFunc)(int status))这个方法可以看出,这个方法的形参是一个函数指针,意思就是说我们要调用者个方法的时候,传入的实参得是一个函数名,在addCallBackFunc的函数体内,只有一句话,就是将形参的函数指正赋值给结构体中函数指针,这样子我们就可以已通过直接使用结构体变量来调用我们传过来的函数。
- 我们再细看传入的实参callBackFunc函数,其实就是一个普通的函数,打印了传入的形参status。
- 现在我们再看run函数,run函数也久三句话,第一句话就是将之前声明的device变量中status赋值为十,后面if判断是判断device的status是否为10,并且它的statusChange是否被赋值了(也就是是否已经指向了一片函数区域)。如果同时存在,执行status.change,并将status作为实参传入。你可以会好奇,之前结构体声明的void (*statusChange)()可是没有参数的,其实啊,我们发现执行的就是callBackFunc函数,而通过addCallBackFunc这个操作,让它可以实现的。
#include <stdio.h>
typedef struct{
int status;
void (*statusChange)();
}T_Device;
T_Device device;
void addCallBackFunc(void (*pFunc)(int status)){
device.statusChange = pFunc;
}
void run(){
device.status = 10;
if(device.status == 10 && device.statusChange != NULL){
device.statusChange(device.status);
}
}
void callBackFunc(int status){
printf("status = %d \n", status);
}
void main(){
addCallBackFunc(callBackFunc);
run();
}