0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言函数的回调函数

工程师 来源:嵌入式客栈 作者:嵌入式客栈 2020-09-11 09:57 次阅读

来源:嵌入式客栈

1 什么是回调函数?首先什么是“回调”呢?

我的理解是:把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调。

如果代码立即被执行就称为同步回调,如果过后再执行,则称之为异步回调。

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

2 为什么要用回调函数?因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。

简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。

int Callback() ///《 回调函数{ // TODO return 0;}int main() ///《 主函数{ // TODO Library(Callback); ///《 库函数通过函数指针进行回调 // TODO return 0;}

回调似乎只是函数间的调用,和普通函数调用没啥区别。

但仔细看,可以发现两者之间的一个关键的不同:在回调中,主程序把回调函数像参数一样传入库函数。

这样一来,只要我们改变传进库函数的参数,就可以实现不同的功能,这样有没有觉得很灵活?并且当库函数很复杂或者不可见的时候利用回调函数就显得十分优秀。

3 怎么使用回调函数?int Callback_1(int a) ///《 回调函数1{ printf(“Hello, this is Callback_1: a = %d ”, a); return 0;}int Callback_2(int b) ///《 回调函数2{ printf(“Hello, this is Callback_2: b = %d ”, b); return 0;}int Callback_3(int c) ///《 回调函数3{ printf(“Hello, this is Callback_3: c = %d ”, c); return 0;}int Handle(int x, int (*Callback)(int)) ///《 注意这里用到的函数指针定义{ Callback(x);}int main(){ Handle(4, Callback_1); Handle(5, Callback_2); Handle(6, Callback_3); return 0;}

如上述代码:可以看到,Handle()函数里面的参数是一个指针,在main()函数里调用Handle()函数的时候,给它传入了函数Callback_1()/Callback_2()/Callback_3()的函数名,这时候的函数名就是对应函数的指针,也就是说,回调函数其实就是函数指针的一种用法。

4 回调函数实例(很有用)一个GPRS模块联网的小项目,使用过的同学大概知道2G、4G、NB等模块要想实现无线联网功能都需要经历模块上电初始化、注册网络、查询网络信息质量、连接服务器等步骤,这里的的例子就是,利用一个状态机函数(根据不同状态依次调用不同实现方法的函数),通过回调函数的方式依次调用不同的函数,实现模块联网功能,如下:

/********* 工作状态处理 *********/typedef struct{ uint8_t mStatus; uint8_t (* Funtion)(void); //函数指针的形式} M26_WorkStatus_TypeDef; //M26的工作状态集合调用函数/************************************************ 》M26工作状态集合函数***********************************************/M26_WorkStatus_TypeDef M26_WorkStatus_Tab[] ={ {GPRS_NETWORK_CLOSE, M26_PWRKEY_Off }, //模块关机 {GPRS_NETWORK_OPEN, M26_PWRKEY_On }, //模块开机 {GPRS_NETWORK_Start, M26_Work_Init }, //管脚初始化 {GPRS_NETWORK_CONF, M26_NET_Config }, /AT指令配置 {GPRS_NETWORK_LINK_CTC, M26_LINK_CTC }, //连接调度中心 {GPRS_NETWORK_WAIT_CTC, M26_WAIT_CTC }, //等待调度中心回复 {GPRS_NETWORK_LINK_FEM, M26_LINK_FEM }, //连接前置机 {GPRS_NETWORK_WAIT_FEM, M26_WAIT_FEM }, //等待前置机回复 {GPRS_NETWORK_COMM, M26_COMM }, //正常工作 {GPRS_NETWORK_WAIT_Sig, M26_WAIT_Sig }, //等待信号回复 {GPRS_NETWORK_GetSignal, M26_GetSignal }, //获取信号值 {GPRS_NETWORK_RESTART, M26_RESET }, //模块重启}/************************************************ 》M26模块工作状态机,依次调用里面的12个函数 ***********************************************/uint8_t M26_WorkStatus_Call(uint8_t Start){ uint8_t i = 0; for(i = 0; i 《 12; i++) { if(Start == M26_WorkStatus_Tab[i].mStatus) { return M26_WorkStatus_Tab[i].Funtion(); } } return 0;}

所以,如果有人想做个NB模块联网项目,可以copy上面的框架,只需要修改回调函数内部的具体实现,或者增加、减少回调函数,就可以很简洁快速的实现模块联网。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7530

    浏览量

    128539
  • 函数
    +关注

    关注

    3

    文章

    3868

    浏览量

    61308
收藏 人收藏

    评论

    相关推荐

    stm32中断函数改变的变量在while中不变怎么解决?

    关于stm32 中断函数改变的变量在while中不变问题
    发表于 04-26 07:44

    stm32cubemx生成rtos后中断处理后执行的函数是否也有优先级?

    如题:函数是否也有优先级,我发现我的函数不能按照预想的来运行.
    发表于 04-25 08:16

    请问ucos-III中断保护放在中断函数还是中断里面?

    请教下ucos-III 中断保护放在中断函数还是中断里面? 1. 中断函数 void DMA2_Stream6_IRQHandler(void) { OS_ERRerr
    发表于 04-23 07:44

    c语言函数函数体用什么符号括起来

    函数 是指将一组能完成一个功能或多个功能的语句放在一起的 代码结构 。 在 C语言程序 中,至少会包含一个函数,及主函数main()。本文将详细讲解关于
    的头像 发表于 11-24 15:52 309次阅读
    c<b class='flag-5'>语言</b>中<b class='flag-5'>函数</b>的<b class='flag-5'>函数</b>体用什么符号括起来

    c语言gets函数可以输入数字吗

    C语言中的gets函数是用来读取字符串的,而不是用来读取数字的。它会读取输入的字符直到遇到换行符或者文件结束符。因此,如果你尝试使用gets函数来读取数字,是无法准确获取数字本身的。 首先,让我们
    的头像 发表于 11-24 10:00 703次阅读

    c语言max函数在哪个库

    C语言的max函数并不属于标准C库,它通常是由程序员自己编写的一个宏定义。max函数用于比较两个数的大小,返回较大的数值。 为了提供更多详实的信息,下面将详细介绍C语言中max
    的头像 发表于 11-22 10:18 1540次阅读

    c语言max函数的使用方法

    C语言是一门广泛使用的编程语言,提供了许多内置的函数来执行各种任务。其中一个非常有用的函数是max函数,它用于比较两个值并返回较大的那个值。
    的头像 发表于 11-22 10:15 5405次阅读

    hal库的中断函数可以重入吗?

    能不能实现中断函数的重入呢
    发表于 10-15 11:32

    C语言中memmove函数的使用

    在C语言编程中,内存操作是不可或缺的一部分,而 memmove 函数是其中一个重要的工具。本文将介绍 memmove 函数的应用场景以及提供详细的示例代码,帮助您更好地理解如何使用这个函数
    发表于 09-13 09:17 679次阅读

    C语言中指针函数函数指针的概念及应用示例

    在C语言中,指针函数函数指针是强大且常用的工具。它们允许我们以更灵活的方式处理函数和数据,进而扩展程序的功能。
    发表于 08-16 16:14 342次阅读

    C语言使用回调函数模拟委托与反射

    函数是C语言的核心概念。主调函数(caller)调用被调函数(callee)是一般的调用关系,如果被调函数(callee)参数包含
    发表于 08-03 16:12 337次阅读

    在哪里可以找到在s32k中配置函数的例子呢?

    嗨社区我需要测量 ptd0、pte11、ptd1 的频率,然后我尝试配置所有通道 iam 配置一个通道,但我配置了输入,它必须调用回函数它没有调用任何
    发表于 06-08 07:35

    RTC alarm组件不进入函数的原因是什么?

    ,cubemx中开启RTC外设,shell输出RTC组件正常,shell中date命令可以设置和查看时间,均正确,但是alarm组件使用时怎么都不进函数,,alarm dump 能看见设置的闹钟,但是不管是
    发表于 05-17 14:14

    MQTT发布新消息时代码中的函数如何继续执行?

    ,换句话说,我不明白每次 MQTT 发布新消息时代码中的函数如何继续执行(因为它应该如此),因为代码位于我的 void setup(
    发表于 05-12 07:11

    MQTT反复重连/函数是怎么回事?

    ,换句话说,我不明白每次 MQTT 发布新消息时代码中的函数如何继续执行(因为它应该如此),因为代码位于我的 void setup(
    发表于 05-12 07:03