函数指针和回调函数的使用方法

了解开发语言的朋友应该都会对回调函数有所了解,在很多的程序开发语言中都能看到回调的身影。 很多场景下,当某个条件成立以后我们希望代码执行某些指定的部分,这个时候可以考虑使用回调函数的方式,这样做思路更加的清晰,也能使代码结构的逻辑更加清晰,结构更加好。
那回调函数到底是什么呢? 它又是怎么实现的呢?
这是本次想要简单分析的一个主题。
但是在说回调函数之前,我觉得很有必要先说明一下 “函数指针” 这个概念,它是回调函数能够实现的重要基础。
1、函数指针学习过c语言的伙伴都知道,c语言中的灵魂 — 指针。 可以毫不犹豫地说,要检验你对c语言的掌握程度,那指针绝对是最好的考察方式。 指针的使用和变幻方式,真正的使用起来能让你眼花缭乱。
下面是常见的指针的定义:
int *ptr1;char *ptr2;struct std *ptr3; // 结构体指针那函数指针到底是什么呢?
函数指针:函数指针是指向函数的指针变量。 简单理解是指向函数名的指针变量。
函数指针既然是指向函数的,那么它就可以像函数一样,用于调用函数、传递参数等操作。 函数指针的定义方式如下:
函数返回值类型 (* 指针变量名) (函数参数列表);“函数返回值类型”:表示该指针变量可以指向具有什么返回值类型的函数;“函数参数列表”:表示该指针变量可以指向具有什么参数列表的函数。举例如下:int (*func1)(void)int (*func2)(int,char,...)char (*func3)(int,char,...)......从上面的演示可以看到,函数指针的定义就是将一个函数中的 “函数名” 改成“(* 指针变量名)”的方式,从而实现了一个函数指针的定义。
但是这里需要注意的是:“(* 指针变量名)”两端的括号是必须要有的,如果缺少了这对括号,那么这个定义的方式就会变为指针函数。 如下:
int *func1(void)int *func2(int,char,...)char *func3(int,char,...)......这种就不是函数指针了,而是指针函数。两者差别是很大的。特别需要需要注意的一点是:指向函数的指针变量没有 ++ 和 -- 运算。
对于函数指针,一般为了方便使用,我们会选择另外的一种定义方式:
typedef 函数返回值类型 (* 指针变量名) (函数参数列表);比如:
typedef int (*fun1)(int,...); typedef int (*fun2)(int, int,...); typedef void (*fun3)(void); typedef void* (*fun4)(void*); ......2.、函数指针的使用方式清楚了函数指针是什么东西了之后,那函数指针要怎么使用呢? 看下面的例子:
/* 1.首先定义一个函数 */int func(int x);/* 2.然后定义一个函数指针 */int (*p) (int x); /* 3.将func函数的首地址赋给指针变量p */p = func;或p = &func; /* 4.然后使用p调用func函数 */(*p) (int x);因为函数名 func 代表函数的首地址,所以经过赋值以后,指针变量 p 保存的就是func的函数入口地址,即 p 就指向函数 func() 代码的首地址。
为了加深函数指针的使用方式,看下面的一段代码你就明白了。 如下:
#include int max(int, int); //函数声明int main(void){ int a, b, c; int(*p)(int, int); //定义一个函数指针 p = max; //把函数max赋给指针变量p, 使p指向max函数 printf(please enter a and b:); scanf(%d %d, &a, &b); c = (*p)(a, b); //通过函数指针调用max函数 printf(a = %d\\nb = %d\\nmax = %d\\n, a, b, c); return 0;}int max(int x, int y) //定义max函数{ int z; if (x > y) z = x; else z = y; return z;}特别注意的是,因为函数名本身就可以表示该函数地址(指针),因此在获取函数指针时,可以直接用函数名,也可以取函数的地址。
3. 函数指针可以作为函数的参数来使用函数指针变量本身也是一个变量,也可以作为某个函数的参数进行使用的。 如下:
#include #include // 定义一个函数指针类型的 funtypetypedef void(*funtype)(int);void myfun(int x);void hisfun(int x);void herfun(int x);void callfun(funtype fp,int x);int main(){ callfun(myfun,1000);//传入函数指针常量,作为回调函数 callfun(hisfun,5000); callfun(herfun,4700); return 0;}4、回调函数前面讲了函数指针,现在终于到了回调函数了。 到这部分,我们就不说太多的废话,直接阐述回调函数是什么,回调函数要怎么使用,一步到位吧!
回调函数:如果一个函数的指针(函数名或地址)作为参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,就说这个指针所指向的函数是一个回调函数。
再简明点说:回调函数不是直接调用该函数进行使用的,而是要通过另外的特定事件或者其他函数进行调用的,才能称作回调函数。 定义一个函数然后直接调用,都不能称为回调函数。
回调函数的定义方式和使用,直接通过下面的例子说明,相信大家一看就会明白。
例程1:
/* 回调函数 */int callback(void) { return 0;}int library(int value,int (*mycallbackfunc)(void)){ if(value == 1)mycallbackfunc(); else return 1;}int main() { library(1,callback); // 返回值为 0return 0;}例程2:
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 myhandle(int x, int (*mycallback)(int)) { mycallback(x);}int main(){ myhandle(4, callback_1); myhandle(5, callback_2); myhandle(6, callback_3); return 0;}从上面的代码可以看出,myhandle() 函数的参数有一个指针,在 main() 函数里调用myhandle() 函数的时候,给它传入了函数 callback_1()、callback_2()、callback_3() 的函数名,这时候的函数名就是对应函数的指针,也就是说,回调函数其实就是函数指针的一种用法。
到此,通过上面的函数指针的说明和回调函数的示例代码,估计看到这里的朋友应该都明白了回调函数的使用了吧!

6p1电子管参数详情
关于推进城轨智能运维发展的几点思考
二十年来目标检测领域的关键技术,思路非常清晰
Facebook做了一份AI年度总结
区块链如何使消费者能够控制他们的数据
函数指针和回调函数的使用方法
轮胎逆向设计解决方案
周志华:中国人工智能活跃度仅次于美国 人工智能研究要靠人的聪明
三星S10新机刚发布 曝光了检测和评分
耐压测试仪的操作方法和测试步骤
预测:到2025年,将有超过400亿个IoT设备
增强现实(AR)与区块链一样,是2018年五大最具突破性的技术之一
昂科ic烧录器更新支持烧录SinoWealth中颖电子的32位微控制器SH30F9020P
专家点赞!国家重点研发计划“六自由度激光自动精准跟踪测量关键技术”项目通过验收
新三板AI企业超音速:宁德时代上游供应商
人工智能则是得以让智能制造实现的重要工具之一
iphone8什么时候上市?iphone8最新消息:iPhone8概念图曝光,三屏幕图标控制+铝合金9000,期待吗?
一文解析USB-C上的数据信号
SMCJ18CA 瞬态抑制(TVS)二极管参数
任意波形/函数发生器AFG3251C的特点优势和应用范围