什么是回调函数( C 语言)?

2015-08-25 23:47:09 +08:00
 silver107

“你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。( by 常溪玲)”

目前处于似懂非懂状态,谁可以帮忙用实例( C 语言)来解析一下怎样是登记回调函数、触发了回调关联的事件、调用回调函数、响应回调事件。

2501 次点击
所在节点    问与答
11 条回复
ljbha007
2015-08-26 00:07:34 +08:00
https://gist.github.com/CarlLee/bef2ded975b24303ba1e

其实说白了就是程序的不同部分之间 用一种事前约定好的形式(一般是一个约定好参数和返回值的函数)

让其中一段程序的编写者不需要知道另一段程序的具体代码的情况下可以通过约定好的协议 在另一段代码某个关键时刻执行自己想要的代码 从而部分控制另一端代码的行为 让程序的不同组建之间可以灵活的通信却不需要每个人都把所有代码读完
Andiry
2015-08-26 00:12:30 +08:00
中断函数就是一种回调函数, epoll 也是用回调实现的。
http://freehui.com/?post=27
fo2w
2015-08-26 00:12:37 +08:00
先生, 您要的薯条我们还在炸
您拿着这号
炸好我们叫您
silver107
2015-08-26 00:27:46 +08:00
@ljbha007 隐约明白。希望能指出哪里是登记(或注册)回调函数
silver107
2015-08-26 00:41:26 +08:00
不知我理解对不对? @ljbha007
on_mouse_clicked 是回调函数
register_mouse_listener (on_mouse_clicked );//登记回调函数
click_mouse (100, 200 );//触发了回调关联的事件
if (NULL != mouse_listener )
(*mouse_listener )(x, y );//调用回调函数 on_mouse_clicked (100,200 );
miniwoodman
2015-08-26 01:22:21 +08:00
理解“回调函数”的前提是了解“函数指针”,之后就自然理解了。

函数指针是一种指针变量,指向的不是数据,而是函数;函数指针可以作为其他函数的参数。让其他函数可以在内部执行调用,但只能按约定好的格式调用(参数类型和参数个数提前约定好)。

#include <stdio.h>

typedef void (*callback_test )(int );

void func_a (int i ){
printf ("this func_a () %i \n", i );
}

void func_b (int i ){
printf ("this func_b () %i \n", i );
}

void func_c (callback_test func ){
func (1 );
func (2 );
}


int main (){

func_c (func_a );
func_c (func_b );
}

----------------------------------------------------
输出:
this func_a () 1
this func_a () 2

this func_b () 1
this func_b () 2
SoloCompany
2015-08-26 02:28:19 +08:00
dont call me
I will call you
pimin
2015-08-26 04:44:28 +08:00
ljbha007
2015-08-26 08:25:17 +08:00
kneep
2015-08-26 09:23:59 +08:00
回调函数不是语言特性,而是设计思想。
lancelot
2015-08-26 10:07:02 +08:00
回调是构成面向对象 C 的必要手段。比如说

typedef UINT32 (* FP_ModInit )(UINT8 ucModID );

UINT32 ModA_ModInit (UINT8 ucModID );
UINT32 ModB_ModInit (UINT8 ucModID );
......

然后这样使用(把 ptModStruct 结构的初始化脑补一下)
case A:
{
ptModStruct.Mod_Init = ModA_ModInit;
......
break;

case B:
{

ptModStruct.Mod_Init = ModB_ModInit;
......
break;

其中左边都是函数指针,右边都是函数名,其实也是函数指针。在不同的 Case 中,我就可以使用相同的函数指针对应到不同的 Mod 初始化函数了。这里是回调的初始化。

在调用的时候,我统一使用 ptModStruct.Mod_Init (ucModID )就可以了,不用管里面被调用的是什么回调函数。

以下是度娘百科

...因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/215981

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX