关于回调函数的理解

关于回调函数的理解

首先说一下回调函数的重要性吧。回调函数最常用于中断处理,而中断处理在嵌入式软件编程中很常见,并且在linux源码中随处可见,所以理解回调函数对我们阅读代码的能力会有很大的提升,同时还能在软件编程时更好地处理中断。总的来说,回调函数适用于截获消息、获取系统信息或处理异步事件。
“把函数做成参数”和“把变量做成参数”目的是一致的,就是以不变应万变。形参是不变的,而实参是可以变化的。所以如果需求改变,我们就可以很灵活地改变实参,调用其他函数处理相应的事件等。

下面我们进入正题:

  1. 回调函数的概念
    回调函数实际上就是通过函数指针调用的函数。如果你把函数指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
    我们抛开表象看本质:回调函数本质其实跟我们平时编程在一个函数中调用另一个函数一样,但是我们平时调用直接把被调函数拿过来用就行了;而回调函数是把被调函数做成一个函数指针,然后将这个函数指针当做形参传给调用函数,这样在调用函数中就可以直接使用被调函数了。
    注意回调函数只能是全局函数或静态函数
  2. 什么是函数指针
    如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示函数的地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。就是指向函数的指针。那么这个指针变量怎么定义呢?虽然同样是指向一个地址,但指向函数的指针变量同指向变量的指针变量的定义方式是不同的。
/*定义一个函数*/
int test(int a, int b)
{
	return a < b ? 1 : 0; 
}
/*定义一个函数指针,指向test函数*/
int (*p)(int a, int b);

  1. 回调函数的举例
/*定义函数指针*/
typedef void (*ListDataPrintFun)(void *data);
/*调用函数*/
static void list_print(ListNode *list, ListDataPrintFun print)
{
	ListNode *temp = list;
	while(temp != NULL)
	{
		print(temp -> data);
		temp = temp -> next;
	}
}
/*被调函数*/
static void list_print_int(void *data)
{
	printf("data = %d", (int)data);
}
/*main函数*/
int main(void)
{
	ListNode *list = list_create();
	/*使用回调函数(也称注册回调函数)*/
	list_print(list,list_print_int);
	return 0;
}

代码说明:
首先,我们需要实现一个通用的list_print函数,把函数指针变量作为其中一个参数传入。
其次,我们调用者得根据实际情况实现一个用于打印的回调函数,这里我们实现的回调函数是list_print_int函数。
最后,在用到打印的地方调用的list_print函数即可。
总的来说,回调函数并不难理解,只是说把一个函数做成函数指针,以传参的方式供其他函数调用,本质和我们常见的传参方式相同。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值