回调函数用简单的例子解释
更新时间:2023-03-28 18:14:01 阅读量: 说明书 文档下载
- c回调函数简单例子推荐度:
- 相关推荐
回调函数的运用
对指针的应用是C语言编程的精髓所在,而回调函数就是C语言里面对函数指针的高级应用。简而言之,回调函数是一个通过函数指针调用的函数。如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数。
为什么要使用回调函数呢?我们先看一个小例子:
Node * Search_List (Node * node, const int value)
{
while (node != NULL)
{
if (node -> value == value)
{
break;
}
node = node -> next;
}
return node;
} 这个函数用于在一个单向链表中查找一个指定的值,返回保存这个值的节点。它的参数是指向这个链表第一个节点的指针以及要查找的值。这个函数看上去很简单,但是我们考虑一个问题:它只能适用于值为整数的链表,如果查找一个字符串链表,我们不得不再写一个函数,其实大部分代码和现在这个函数相同,只是第二个参数的类型和比较的方法不同。 其实我们更希望令查找函数与类型无关,这样它就能用于查找存放任何类型值的链表了,因此必须改变比较的方式,而借助回调函数就可以达到这个目的。我们编写一个函数(回调函数),用于比较两个同类型的值,然后把一个指向这个函数的指针作为参数传递给查找函数,查找函数调用这个比较函数来执行比较,采用这个方法,任何类型的值得都可以进行比较。
我们还必须给查找函数传递一个指向待比较的值的指针而不是值本身,也就是一个void *类型的形参,这个指针会传递给回调函数,进行最终的比较。这样的修改可以让我们传递指向任何类型的指针到查找函数,从而完成对任何类型的比较,这就是指针的好处,我们无法将字符串、数组或者结构体作为参数传递给函数,但是指向它们的指针却可以。
现在,我们的查找函数就可以这样实现:
NODE *Search_List(NODE *node, int (*compare)(void const *, void const *) , \
void const *desired_value);
回调函数的运用
while (node != NULL)
{
if (compare((node->value_address), desired_value) == 0)
{
break;
}
node = node->next;
}
return node;
}
可以看到,用户将一个函数指针传递给查找函数,后者将回调这个函数。
注意这里我们的链表节点是这样定义的:
typedef struct list
{
void *value_address;
struct list *next;
}NODE; 这样定义可以让NODE *类型的指针指向存储任何类型数据的链表节点。而
value_address就是指向具体数据的指针,我们把它定义为void *,表示一个指向未知类型的指针,这样链表就可以存储任何类型的数据了,而我们传递给查找函数Search_List的第一个参数就可以统一表示为:NODE *,否则,还是要分别写查找函数以适应存储不同数据类型的链表。
现在,查找函数与类型无关,因为它不进行实际的比较,因此,我们必须编写针对不同类型的比较函数,这是很容易实现的,因为调用者知道链表中所包含的值的类型,如果创建几个分别包含不同类型值的链表,为每种类型编写一个比较函数就允许单个查找函数作用于所有类型的链表。
下面是一个比较函数,用于在一个整型链表中查找:
注意强制类型转换,比较函数的参数必须被声明为void *以匹配查找函数的原型,然后强制转换为(int *)类型用于比较整型。
int int_compare(void const *a, void const *b)
{
if (*(int *)a == *(int *)b)
回调函数的运用
return 0;
}
else
{
return -1;
}
}
这个函数可以这样被使用:
desired_node = Search_List(root, int_compare, &desired_int_value); 如果你希望在一个字符串链表中进行查找,下面的代码就可以完成任务:
desired_node = Search_List(root, strcmp, “abcdefg”); 正好库函数strcmp所执行的比较和我们需要的一样,不过gcc会发出警告信息:因为strcmp的参数被声明为const char *而不是void const *。 上面的例子展示了回调函数的基本原理和用法,回调函数的应用是非常广泛的。通常,当我们想通过一个统一接口实现不同内容的时候,用回调函数来实现就非常合适。任何时候,如果你所编写的函数必须能够在不同的时刻执行不同的类型的工作或者执行只能由函数调用者定义的工作,你都可以用回调函数来实现。许多窗口系统就是使用回调函数连接多个动作,如拖拽鼠标和点击按钮来指定调用用户程序中的某个特定函数。
「回调函数是由系统调用的」—— callback 不是由系统调用的。正确的流程为:
1.
2.
3.
4.
5.
6. 用户的输入设备发送信息给 device driver。 Device driver 将信息发给某些 manager 程序。比如说,大多数鼠标和键盘动作都会传给 window manager。 Window manager 会把这些动作翻译成 event,通过 IPC 机制传给 app。 App 的 UI framework 会把这些通过 IPC 接受到的 event 放到 event-queue 中。 你自己,或者 UI framework 会运行一个 loop。这个 loop 不停的去 event-queue 中取 event。 如果取到,event-loop 会调用相应的 callback。
在 callback 中加断点,用 debugger 调试,你会在 callstack 中看到从 event-loop 到你的 callback 的一系列调用。
正在阅读:
回调函数用简单的例子解释03-28
安徽省六安市毛坦厂中学2013届高三一模数学文试题-Word版含答案11-26
定积分讲义09-17
浙江省金华市东阳市事业单位考试《计算机专业知识》试题08-07
期中考试家长会总结表彰大会校长演讲稿03-06
TinyOS 2.x 入门教程 - 图文06-07
《刑辩之鉴》读后感12-12
2015黄珠洲六一文艺汇演活动方案07-21
做过使自己自豪的事作文300字07-03
老婆生气了哄老婆的话02-15
- 马克思主义原理考试范围Microsoft Word 文档 (3)
- 地热发电市场行情现状及投资调查行业报告2018年目录
- 鸿合白板软件安装图示
- 水泥厂高压风机节能技改简述
- TS16949体系程序文件清单(过程识别)
- 生产部质量管理体系运行及内审报告
- 【精】消防应急照明和疏散指示系统检测与维护
- 课前三分钟----安全教育
- 语文一年级上册学前教育
- 腐败案警示录观后感
- 宜春野外拓展训练方案
- 商业银行经营绩效评价指标体系有哪几类构成?各自侧重分析哪些方
- gb29639-生产经营单位生产安全事故应急预案编制导则
- 晴隆县碧痕小学麻风病防治工作总结
- 2015陕西政法干警行测指导:用矛盾解决直言命题里的真假话问题
- 年度版2014年大学英语B统考题库模拟测验卷五
- 2020年度注册咨询师《FIDIC合同条件及要点分析》试卷及答案
- 大猫老师的绘本作文课
- Word长文档排版(素材)
- 07线性代数练习题(含答案)
- 回调
- 函数
- 例子
- 解释
- 简单
- (完整版)公路招投标文件-初步设计
- 汽车涂装桔皮成因浅析及排除方法
- 村落整治工程项目建议书申请报告可行性研究报告
- 二年级下册数学试卷分析
- 公文写作基础知识及应用
- e-learning解决方案
- 食品安全监管的重要性
- 15 种常用的凉菜调味汁
- 冠脉造影的适应症及禁忌症
- 2019四年级下册英语教案Lesson2Whatareyoudoing∣鲁科版(五四学
- 人教版三年级语文下册第八单元试卷(含答案)
- 南京青奥体育公园演示文稿
- 酚氯仿法提取DNA的一些试剂的作用
- 高中数学中对称性问题
- 2013年事业单位招聘考试公共基础知识:文学常识(中国)
- 人教版三年级数学上册分数的初步认识课件
- 复方中药葛花解酲汤对酒精性脂肪肝大鼠模型的影响
- 2010年危险化学品烟花爆竹安全监管和非药品类易制毒化学品监管重
- 宝玉石鉴定与加工技术专业开题报告范文最新原创模板
- 淮阴工学院c++实验报告实验四循环结构的程序设计