可以看到,回调函数通常和应用处于同一抽象层(因为传入什么样的回调函数是在应用级别决定的)。而回调就成了一个高层调用底层,底层再回过头来调用高层的过程。
#include
#include
//函数指针结构体
typedef struct _OP {
float (*p_add)(float, float);
float (*p_sub)(float, float);
float (*p_mul)(float, float);
float (*p_div)(float, float);
} OP;
//加减乘除函数
//回调函数1
float ADD(float a, float b)
{
return a + b;
}
//回调函数2
float SUB(float a, float b)
{
return a - b;
}
//回调函数3
float MUL(float a, float b)
{
return a * b;
}
//回调函数4
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 = ÷
}
//中间函数(库函数)
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));
return 0;
}
这个例子有点长,一步步地来讲解如何使用回调函数。
// 加减乘除函数
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 = ÷
}
下述做法等同:
//typedef定义一种新类型:P_ADD。该类型是一个函数,参数为(float, float),返回值为float。
typedef float(P_ADD)(float, float);
typedef float(P_SUB)(float, float);
typedef float(P_MUL)(float, float);
typedef float(P_DIV)(float, float);
//定义函数指针
typedef struct _OP
{
P_ADD *p_add;
P_SUB *p_sub;
P_MUL *p_mul;
P_DIV *p_div;
}
//初始化函数指针
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));
简单的四部便可以实现回调函数。在这四步中,我们甚至可以省略第二步,直接将函数名传入“库函数”,比如上面的乘法和除法运算。
void stable_sort(vector::iterator iterBegin, vector::iterator iterEnd, bool (*isShorter)(const string &, const string &));
其中前面两个是普通参数,即迭代器(用于标记vector容器里面元素的位置),而第三个参数isShorter就是回调函数。根据不同需求isShorter可以有不同的实现,包括函数名。比如:
bool myIsShorter(const string &s1, const string &s2)
{
return s1.size()
根据需求你也可以换一种方式来实现。
注意,在传递myIsShorter这个参数时,只需写函数名,它代表函数指针,后面不能加()和参数。在stable_sort运行时,当遇到需要比## 标题文字 ##较两个单词的长短时,就会对myIsShorter进行调用,得到一个判断。
https://www.zhihu.com/question/19801131
https://segmentfault.com/a/1190000008293902#articleHeader3