来源:嵌入式客栈

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语言的异步回调函数,C语言函数的回调函数相关推荐

  1. c语言timer linux 回调函数_C语言回调函数详解

    1. 什么是回调函数? 回调函数,光听名字就比普通函数要高大上一些,那到底什么是回调函数呢?恕我读得书少,没有在那本书上看到关于回调函数的定义.我在百度上搜了一下,发现众说纷纭,有很大一部分都是使用类 ...

  2. c语言回调函数_C语言学习第26篇---函数与指针分析 回调函数

    函数类型的概念 1.C语言函数也是有类型的 2.函数类型由函数返回值,参数类型,参数个数共同决定 int add(int i,int j) 的类型是 int(int , int) 3.C语言中通过ty ...

  3. c语言函数指针封装函数,C语言之函数指针、回调函数的使用

    一.背景 首先看下如下代码,这个定义是放在头文件的,在程序中tCdrvCallbackFkt也定义了另一个变量,而且括号后面还跟定义了几个变量,不理解这个定义. typedef void (PUBLI ...

  4. c语言callback函数用法,C函数回调(callback)C++类成员函数的方法

    问题的由来 C回调的步骤一般是: 声明callback函数类型: 根据类型定义一个callback函数A: 把定义的函数A,作为参数传入到另外一个函数B: 函数B会在某个时刻,调用A. 因为C里面函数 ...

  5. arg是什么函数_C 语言编程 — 函数

    函数 函数的本质就是针对变量的操作过程,同时可能也会改变当前程序的状态.它接受多个输入值,计算并返回一个输出值. 函数大体上分为 3 类: 主函数:每个 C 程序都至少有一个 main(). 内置函数 ...

  6. C/C++ atol函数- C语言零基础入门教程

    目录 一.ltoa 函数简介 二.int/long/unsigned long 区别 1.无符号整形(16 位系统) 2.有符号整形(16 位系统) 3.int 和 long 区别 三.atol 函数 ...

  7. C/C++ strtol 函数 - C语言零基础入门教程

    目录 一.strtol 函数简介 二.strtol 函数函数实战 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 一.strtol 函数简 ...

  8. C/C++ strtod函数 - C语言零基础入门教程

    目录 一.strtod 函数简介 二.strtod 函数函数实战 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 一.strtod 函数简 ...

  9. C/C++ ultoa函数 - C语言零基础入门教程

    目录 一.ltoa 函数简介 二.int/long/unsigned long 区别 1.无符号整形(16 位系统) 2.有符号整形(16 位系统) 3.int 和 long 区别 三.ultoa 函 ...

  10. C/C++ ltoa函数 - C语言零基础入门教程

    目录 一.ltoa 函数简介 二.int 和 long 区别 三.ltoa 函数函数实战 四.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门 ...

最新文章

  1. 我们是如何陷入贫穷与忙碌的?
  2. SEH(结构化异常处理)
  3. C#decimal数据类型——有效长度问题
  4. 李航《统计学习方法》-----支持向量机
  5. 阿里如何做到百万量级硬件故障自愈?
  6. 信息学奥赛C++语言:斗转星移
  7. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序使用高级功能...
  8. 转贴: mysql-5.7.20 编码由 utf8 改为 utf8mb4
  9. python 编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址_[LeetCode] 468. 验证IP地址
  10. 教育实习手册高中计算机,计算机教育实习论文大纲格式模板 计算机教育实习论文框架如何写...
  11. 第九届蓝桥杯JavaC组省赛真题
  12. 扫描全能王完美版,纸质文件一键识别电子文档
  13. big O notation - 大 O 表示法
  14. 3款好用的文件管理软件
  15. Python----python手机号码格式校验
  16. MsCOCO数据集标注详解
  17. Anaconda安装并配置
  18. 阿里云下部署es单机
  19. mysql向上向下递归查询父集子集
  20. Ground truth 在计算机方面的意思

热门文章

  1. 2011戴尔计算机配置,机型与配置(一)
  2. CSF文件格式播放器
  3. mysql-入门教程
  4. 反恐精英代码_知名网游源代码泄漏 ,外挂潮将来?
  5. 全网最快的网络服务器是什么,最好用最快的首选 DNS 服务器地址设置 (电信/联通/移动)...
  6. linux系统用虚拟光驱装win7,用虚拟光驱加载win7或者xp iso镜像文件安装系统的图解步骤...
  7. 网络编程在线英英词典之登录模块实现(四)
  8. 13.软件架构设计:大型网站技术架构与业务架构融合之道 --- 业务意识
  9. 常见的SQL面试题:经典50例
  10. SQL查询语句大全(大佬总结,必看)