C语言函数指针之回调函数

2022-12-18 0 634

1 甚么是反弹表达式?

具体来说甚么是“反弹”呢?

我的认知是:把几段可继续执行的标识符像HTA那般传予其它标识符,而那段标识符会在某一关键时刻被初始化继续执行,这就叫作反弹

假如标识符立刻被继续执行就称作并行反弹,假如之后再继续执行,则称之为触发器反弹

反弹表达式是两个透过初始化的表达式。假如你把表达式的操作符(门牌号)做为HTA给另两个表达式,当那个操作符被用以初始化其所对准的表达式时,他们就说这是反弹表达式。

反弹表达式并非由该表达式的同时实现方间接初始化,而要在某一的该事件或前提出现时由除此之外的另一方初始化的,用作对该该事件或前提展开积极响应。

2 为甚么要用反弹表达式?

即使能把初始化者与被初始化者合二为一,因此初始化者不重视谁是被初始化者。它只需晓得存有两个具备某一蓝本和管制前提的被初始化表达式。

具体来说,反弹表达式是容许采用者把须要初始化的方式的操作符做为HTA给两个表达式,以期该表达式在处置相近该事件的这时候能灵巧的采用相同的方式。

C语言函数指针之回调函数

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_LINK_FEM, M26_LINK_FEM }, //连接前置机

{GPRS_NETWORK_COMM, M26_COMM }, //正常工作

{G

{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++表达式操作符与操作符表达式

C词汇操作符详解

举报/反馈

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务