搞定C语言回调函数

来源:互联网 发布:美国陆军头盔淘宝 编辑:程序博客网 时间:2024/05/17 05:50

        回调函数是老生常谈的事情,一名基本熟练C语言语法的编程者,在慢慢成为一定经验的编程者的过程中,想必都会经历熟练使用回调函数的阶段,这也是很多企业在面试时喜欢考察的技术题之一。


一、定义

        回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

举个例子,通俗一点讲是这个样子:

        诸葛亮给赵子龙一个锦囊,吩咐他危急时打开按锦囊指示办,锦囊里的命令就是回调函数,危急时刻就是回调的时机。

还有一个例子:

        设想你是某高大上企业老总,你要出国度假,临走前你只把一个私人电话号码(回调函数的地址)留给前台MM,告诉她,如果王思聪来找我(回调条件),你就给打这个电话Call(回调)我和他谈事情(回调函数)。

        简而言之,回调函数是一个通过函数指针调用的函数。如果你把函数指针(函数的入口地址)传递给另一个函数,当这个函数指针被用来调用它所指向的函数时,我们就说这个函数是回调函数。对指针的应用是C语言编程的精髓所在,而回调函数就是C语言里面对函数指针的高级应用。

        我们提到了函数指针,就拓展一下“函数指针”和“指针函数”。

        函数指针:函数指针是指向函数的指针变量。因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数。

        指针函数:指针函数是指函数返回值带指针的函数,即本质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。


二、使用

(1)定义回调函数指针

既然说回调函数是一个通过函数指针调用的函数,那么这个函数指针该如何定义呢?我们经常会定义各种不同类型的指针,如

int *ptr;  //整型指针char *ptr;  //字符型指针 struct my_struct *ptr;  //结构体指针

同理,函数指针(指向函数的指针变量)一般定义方法为:  返回值类型 (*指针变量名)(函数参数列表)如

int (*ptr)(int, int);  //int代表这个函数的返回值类型,ptr代表这个函数指针的名字,(int,int)代表传入函数的是两个int型参数

如果你要问函数指针为什么要这么定义,请先回答为什么整型指针的定义方式为 int *ptr 。

我们根据需要可以定义出各种所需的函数指针:

int (*ptr1)(void);//返回值类型为int,名字为ptr1,无形参的回调函数指针void (*ptr2)(char* ,struct my_struct*, enum my_enum);//返回值类型为无类型,名字为ptr2,参数含有字符型指针、结构体指针、枚举类型的回调函数指针……


但是,注意了!我们通常不会以上述方式去定义函数指针,而是通过typedef关键字,为回调函数指针命名,使代码更具有可读性。
typedef int (*callBackFun)(char *); // 为回调函数指针命名,指针变量名为 callBackFun,参数为char *,等价于int (*ptr)(char *);

(2)定义回调函数

其实就是写一个普通的函数,里面含有当这个回调函数被调用时,要做的事情,如
int func_callBack(char *my_string){printf("%s\r\n", my_string);}
(3)定义回调条件
仍旧是写一个普通的函数,里面可以定义回调时机,或者说是回调条件
int func(int handle_flag, char *date, callBackFun cb){if(handle_flag == 1)cb(data);return 0;}


(4)执行回调函数
void main(void){char data[256]="Learn how to use call back func";func(1, data, func_callBack);}


运行结果:


欧了 ,搞定!


源代码:
#include <string.h>typedef int (*callBackFun)(char *);int func_callBack(char *my_string){printf("%s\r\n", my_string);return 0;}int func(int handle_flag, char *data, callBackFun cb){if(handle_flag == 1)cb(data);return 0;}void main(void){char data[256]="Learn how to use call back func";func(1, data, func_callBack);}



0 0
原创粉丝点击