提到回调函数,我也顺手在网上翻了一下,我发现说的都比较详细甚至于冗长了很多人的解说都比较类似,回想当初自己刚接触的时候,我打算从一个非常简单的角度用几段话说完回调函数的使用和理解,今天小编就来说说关于回调函数用在哪个函数中?下面更多详细答案一起来看看吧!

回调函数用在哪个函数中(回调函数最简单的理解方式)

回调函数用在哪个函数中

提到回调函数,我也顺手在网上翻了一下,我发现说的都比较详细甚至于冗长了。很多人的解说都比较类似,回想当初自己刚接触的时候,我打算从一个非常简单的角度用几段话说完回调函数的使用和理解。

重点来了:什么是回调函数

在程序中把你的函数换成函数指针,用指针去替代你本该写的函数名,这个被替代的函数就是回调函数。

结束!

用个简单的代码演示一下

//这里是它的头文件 Led.h #ifndef __LED_H__ #define __LED_H__ void Led_On(void); #endif //这里是一个文件 Led.c //这是一个函数,假设它有个功能,就是点亮LED灯 void Led_On(void) { LED = TRUE; }

这里有另一个程序文件

//这里是它的头文件 #ifndef __SWITCH_H__ #define __SWITCH_H__ #include "Led.h" //方法一,引用LED头文件 void Get_Switch_State(void); #endif //这里是另一个文件 switch.c //这里有另一个函数,假设它检测到某信号后需要点亮LED灯和处理一些事情; extern void Led_On(void); //方法二,外部申明一下Led_On函数,如此才能跨函数调用 void Get_Switch_State(void) { if (Signel == TRUE) Led_On(); //调用Led_On()函数,实现点亮LED功能 //....... //do something } /* 要想能正常调用Led_On()函数,必须使用以上两个方法之一 */

上面就是一个普通的程序流程,流程中有个普通的函数调用,如果,我将Get_Switch_State()中的Led_On()更换成指向Led_On()函数的函数指针,那么这时候Led_On就成了回调函数。

还是在另一个程序文件中

//这里是它的头文件 #ifndef __SWITCH_H__ #define __SWITCH_H__ #typedef void(*pFun)(void); //函数指针原型定义 重点一 void Get_Switch_State(void); void CallBack_Reg(pFun cb); #endif //这里是另一个文件 switch.c //这里有另一个函数,假设它检测到某信号后需要点亮LED灯和处理一些事情; pFun CallBack_Ptr; //定义一个函数指针 重点二 //回调函数的注册函数CallBack_Reg() void CallBack_Reg(pFun cb) { if (CallBack_Ptr == 0) //为函数指针赋值,当然它首先要没有被赋值 CallBack_Ptr = cb; } void Get_Switch_State(void) { if (Signel == TRUE) CallBack_Ptr(); //调用Led_On()函数的指针,实现点亮LED功能 重点三 //....... //do something } /* 发现关键点没有? switch.c 中再也没有出现Led_On();那它如何实现调用? 答案是还需要在其它地方 比如说main函数中把Led_On()函数和CallBack_Ptr 这个指针绑定一下 */ void main(void) { Gpio_Init(); Bsp_Init(); Timer_Init(); CallBack_Reg(Led_On); //重点四 while (1) { ....... } }

从上面的代码中可以明显发现几个特点

1.switch.c和.h中没有出现Led_On()函数了。 Led_On()函数被函数指针CallBack_Ptr替代了。

2.switch.c和.h中没有在引用文件Led.h了,实现了两个c文件的解耦,使他们的关联性降低了。

此时函数Led_On()就可以被称作 回调函数 了。

讲解完毕~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

好像还有点意犹未尽

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

总结一下,不要被回调函数的各种高深讲解给弄晕了头脑,它实际就是将你的函数用函数指针替代了,函数指针中存放的就是你的函数地址。

为了让函数指针CallBack_Ptr能指向你Led_On()的地址,你需要做一个注册功能函数CallBack_Reg(),将你要调用的函数地址传递给函数指针CallBack_Reg(Led_On);即CallBack_Ptr = Led_On。

这样,在调用CallBack_Ptr 的时候就等于调用了Led_On。

完美解决。。

最后说明一下函数指针的定义

typedef void(pFun *)(void); //第一个void表示指向的函数返回参数为空,第二个void表示输入参数为空

对比一下它要指向的函数 void Led_On(void) ; 数数void数量和位置理解了吧。

那如果有个函数带有输入参数怎么办呢?

聪明的你一定想到了

typedef void( pFun *)(unsigned char);

它可以指向的函数就如同 void Led_OnOff(unsigned char ) ;

使用

pFun CallBack_Ptr ; //定义函数指针

..........//注册函数指针

CallBack_Ptr (InputDat); //使用函数指针,并传递值InputDat给了函数

.........

对于有返回值和多个输入参数的函数就希望聪明的你举一反三了!

完毕!

,