数码之家

 找回密码
 立即注册
搜索
查看: 974|回复: 8

[STM] 实践理解 函数指针和回调函数

[复制链接]
发表于 2024-7-29 11:01:16 | 显示全部楼层 |阅读模式
本帖最后由 inthsunshine 于 2024-7-29 11:27 编辑

前阵子看一个解码器的资料,输入数据是以回调函数形式实现,之前也一直没留意没用过,得赶紧补缺补漏

自己写了简单的测试程序运行,更好理解它们

首先是函数指针的定义,和函数定义有点象
uint8_t (*func_pt)(uint8_t a);   //形参的参数名不写也可以编译通过,比如去掉a, (uint8_t)
另一种定义方法
typedef uint8_t (*func_pt1)(uint8_t);
func_pt1 func_pt;

所谓的函数指针,本质上就是一个指针变量,指向函数的变量, 和普通的指针变量类似
翻看编译后的map表,在内存占用4字节, 存储的是地址


为了使用函数指针,先定义2个简单函数,这2个函数的返回值和参数和前面的函数指针是完全一样
uint8_t callback1(uint8_t a) { return (a+1); }
uint8_t callback2(uint8_t a) { return (a-1); }

既然是函数指针,自然可以使用它,比如
  uint8_t tmp;
  func_pt=&callback1;    //给指针赋值
  tmp=(*func_pt)(6);    //调用callback1,也可写成func_pt(6)
  func_pt=callback2;      //也可以把取地址符号&去掉,同数组名类似,函数名也代表起始地址
  tmp=(*func_pt)(6);    //调用callback2

当然也可以定义函数指针数组
uint8_t (*callbackfunc[]) (uint8_t)={callback1,callback2};
再调用
func_pt=callbackfunc[1];
tmp=(*func_pt)(6);    //调用callback2

关键来了,函数可以成为另一个函数的入口参数,也就是函数可以当成参数传递。
比如以下函数,第2个参数是函数指针
uint8_t b(uint8_t c, uint8_t (*func)(uint8_t))    //或者uint8_t b(uint8_t c, func_pt1 func)
{  ....
   return (*func)(c); }

调用该函数
tmp=b(6,callback1);   //调用callback1
tmp=b(6,callback2);   //调用callback2
调用b函数时,需要提供另一个函数名作为参数,然后b运行后,会执行传递过来的函数,比如callback1,callback2,那么这2个函数称为回调函数

从编译后的汇编程序看,调用b函数时,第一个参数传给内部寄存器r0, 第二个参数传给r1,也就是callback1的地址
在b函数内部,传递过来的r1,最后成了跳转指令的目标地址,实现执行回调函数callback1


使用回调函数的好处是,假设b函数里面有一些是每次都要执行的固定操作,有些是根据情况执行可变的操作,那么,可以保持不修改b程序的情况下,通过传递不同的函数,来实现可变操作,这样的b函数通常是底层函数,可以和应用程序做分离。

不过话说回来,一个人就可完成的不大的diy程序,用到回调函数的必要性不大,或者说可以用if语句也能实现类似的功能,大概比较规范的代码,或者多人协作的大程序才需要吧。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 2家元 +90 收起 理由
慕名而来 + 30 謝謝分享
家睦 + 60

查看全部打赏

发表于 2024-7-29 11:20:21 | 显示全部楼层

c/c++的mqtt库,就经常有回调。
回复 支持 反对

使用道具 举报

发表于 2024-7-29 12:05:27 | 显示全部楼层
MCU的C代码会频繁用回调函数,类似于数组调用经常用指针,ADC,EEPROM读写等.
回复 支持 反对

使用道具 举报

发表于 2024-7-29 14:32:26 | 显示全部楼层
回调函数最大的作用就是解耦
回复 支持 反对

使用道具 举报

发表于 2024-7-29 20:23:15 | 显示全部楼层
仔细看了两遍,好像懂了又好像不懂,还要慢慢的转弯。
回复 支持 反对

使用道具 举报

发表于 2024-7-31 12:11:56 | 显示全部楼层
回调函数算是常用用法了.
函数指针可以用来模拟c++的类继承, 实现一定的按类型调度.
回复 支持 反对

使用道具 举报

发表于 2024-8-3 12:38:54 | 显示全部楼层
回调函数的实现很简单,关键是要知道为什么要用回调函数这才是关键
回复 支持 反对

使用道具 举报

发表于 2024-8-24 11:10:07 | 显示全部楼层
学到了:
使用回调函数的好处是,假设b函数里面有一些是每次都要执行的固定操作,有些是根据情况执行可变的操作,那么,可以保持不修改b程序的情况下,通过传递不同的函数,来实现可变操作,这样的b函数通常是底层函数,可以和应用程序做分离。
回复 支持 反对

使用道具 举报

发表于 2024-8-24 14:57:49 | 显示全部楼层
从委托角度看,当发生了某一事件,会自动调用之前委托的函数!道理不复杂,关键是具体怎么做!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-4 01:29 , Processed in 0.124800 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表