转·带你⽤实例理解C语⾔回调函数
前⾔:
什么是回调函数
我们先来看看百度百科是如何定义回调函数的:
回调函数就是⼀个通过函数指针调⽤的函数。如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。
这段话⽐较长,也⽐较绕⼝。下⾯我通过⼀幅图来说明什么是回调:
假设我们要使⽤⼀个排序函数来对数组进⾏排序,那么在主程序(Main program)中,我们先通过库,选择⼀个库排序函数(Library function)。但排序算法有很多,有冒泡排序,选择排序,快速排序,归并排序。同时,我们也可能需要对特殊的对象进⾏排序,⽐如特定的结构体等。库函数会根据我们的需要选择⼀种排序算法,然后调⽤实现该算法的函数来完成排序⼯作。这个被调⽤的排序函数就是回调函数(Callback function)。
结合这幅图和上⾯对回调函数的解释,我们可以发现,要实现回调函数,最关键的⼀点就是要将函数的指针传递给⼀个函数(上图中是库函数),然后这个函数就可以通过这个指针来调⽤回调函数了。注意,回调函数并不是C语⾔特有的,⼏乎任何语⾔都有回调函数。在C语⾔中,我们通过使⽤函数指针来实现回调函数。那函数指针是什么?不着急,下⾯我们就先来看看什么是函数指针。
回调函数
现在我们回到正题,来看看回调函数到底是怎样实现的。下⾯是⼀个四则运算的简单回调函数例⼦:
#include <stdio.h>
#include <stdlib.h>
/****************************************
* 函数指针结构体
***************************************/
typedef struct _OP {
float (*p_add)(float, float);
float (*p_sub)(float, float);
float (*p_mul)(float, float);
float (*p_div)(float, float);
} OP;
/****************************************
* 加减乘除函数
***************************************/
float ADD(float a, float b)
{
return a + b;
}
float SUB(float a, float b)
{
return a - b;
}
float MUL(float a, float b)
{
return a * b;
}
float DIV(float a, float b)
{
return a / b;
}
/****************************************
* 初始化函数指针
***************************************/
void init_op(OP *op)
{
op->p_add = ADD;
op->p_sub = SUB;
op->p_mul = &MUL;
op->p_div = &DIV;
}
c语言的冒泡排序算法/****************************************
* 库函数
***************************************/
float add_sub_mul_div(float a, float b, float (*op_func)(float, float))
{
return (*op_func)(a, b);
}
int main(int argc, char *argv[])
{
OP *op = (OP *)malloc(sizeof(OP));
init_op(op);
/* 直接使⽤函数指针调⽤函数 */
printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n", (op->p_add)(1.3, 2.2), (*op->p_sub)(1.3, 2.2),            (op->p_mul)(1.3, 2.2), (*op->p_div)(1.3, 2.2));
/* 调⽤回调函数 */
printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n",
add_sub_mul_div(1.3, 2.2, ADD),
add_sub_mul_div(1.3, 2.2, SUB),
add_sub_mul_div(1.3, 2.2, MUL),
add_sub_mul_div(1.3, 2.2, DIV));
return0;
}
这个例⼦有点长,我⼀步步地来讲解如何使⽤回调函数。
第⼀步
要完成加减乘除,我们需要定义四个函数分别实现加减乘除的运算功能,这⼏个函数就是:
/****************************************
* 加减乘除函数
***************************************/
float ADD(float a, float b)
{
return a + b;
}
float SUB(float a, float b)
{
return a - b;
}
float MUL(float a, float b)
{
return a * b;
}
float DIV(float a, float b)
{
return a / b;
}
第⼆步
我们需要定义四个函数指针分别指向这四个函数:
/****************************************
* 函数指针结构体
***************************************/
typedef struct _OP {
float (*p_add)(float, float);
float (*p_sub)(float, float);
float (*p_mul)(float, float);
float (*p_div)(float, float);
} OP;
/
****************************************
* 初始化函数指针
***************************************/
void init_op(OP *op)
{
op->p_add = ADD;
op->p_sub = SUB;
op->p_mul = &MUL;
op->p_div = &DIV;
}
第三步
我们需要创建⼀个“库函数”,这个函数以函数指针为参数,通过它来调⽤不同的函数:
/****************************************
* 库函数
***************************************/
float add_sub_mul_div(float a, float b, float (*op_func)(float, float))
{
return (*op_func)(a, b);
}
第四步
当这⼏部都完成后,我们就可以开始调⽤回调函数了:
/* 调⽤回调函数 */
printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n",
add_sub_mul_div(1.3, 2.2, op->p_add),
add_sub_mul_div(1.3, 2.2, op->p_sub),
add_sub_mul_div(1.3, 2.2, MUL),
add_sub_mul_div(1.3, 2.2, DIV));
简单的四部便可以实现回调函数。在这四步中,我们甚⾄可以省略第⼆步,直接将函数名传⼊“库函数”,⽐如上⾯的乘法和除法运算。回调函数的核⼼就是函数指针,只要搞懂了函数指针再学回调函数,那真是⼿到擒来了。
如有侵权,望告知删帖。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。