首先,我们回忆一下,标准库函数printf是如何被我们调用的。
1. 包含库函数所在的头文件 #include <stdio.h>
2. 调用printf,例如printf("Hello World");
3. 编译、运行,屏幕上输出了Hello World。搞定!
很好,我们就是这样调用标准库函数的。现在,假设有另外一个库函数myLib_ancient_times,它在被调用时,需要传入一个函数指针。
myLib_ancient_times(funPtr_modern_times);
奇妙的事情发生了,我们可以穿越了。
提问:“传送门”是指什么?
答案:函数指针,指向函数funPtr_modern_times。
下面回归主题,什么是回调函数。答对了,就是“传送门”!
输了这么多,是否感觉有那么一点点明白回调函数是什么了?接下来,我们通过实现一个计算器来更进一步理解回调函数。
目标:
实现一个计算器,可以实现正整数的加减乘除四则运算。
分析:
1. 输入的取值范围:0~9、+、-、*、/、=或回车
2. 输出:四则运算的计算结果,只显示整数部分
实现代码示例:
#include <stdio.h>
//calculator_lib.h
typedef void (* calculator_callback_function)
(
int operator,
void * buf,
int buf_len
);
calculator_callback_function cal_cb;
typedef enum{
ADD,
SUB,
MUL,
DIV
}cal_ind_e;
typedef struct{
int res;
}cal_ind_content_t;
void cal_init(calculator_callback_function);
//calculator_lib.c
void cal_init(calculator_callback_function cb)
{
cal_cb = cb;
}
void cal()
{
int a,b;
char op;
cal_ind_content_t cal_ind;
while(scanf("%d", &a)){
scanf(" %c", &op);
scanf("%d", &b);
switch(op)
{
case '+':
cal_ind.res = a + b;
cal_cb(ADD, &cal_ind, sizeof(cal_ind));
break;
case '-':
cal_ind.res = a - b;
cal_cb(SUB, &cal_ind, sizeof(cal_ind));
break;
case '*':
cal_ind.res = a + b;
cal_cb(ADD, &cal_ind, sizeof(cal_ind));
break;
case '/':
cal_ind.res = a / b;
cal_cb(SUB, &cal_ind, sizeof(cal_ind));
break;
default:
printf("ERROR: Not supported operation.\n");
break;
}
}
}
//app.c
void app_cal_cb(int op, void * buf, int buf_len)
{
int res = *( (int*)buf );
printf("%d\n", res);
}
int main()
{
int a,b;
char op;
cal_init(app_cal_cb);
cal();
return 0;
}
示例中,calaulator_lib模块通过回调函数将计算结果传递给了app模块。app模块通过回调函数实现了打印计算结果的功能。
在实际应用中,回调函数应用十分普遍,希望本文可以帮助你更好地理解回调函数。
练习:库函数qsort()是一个回调函数使用的例子。请使用qsort实现对一组数据的升序、降序排列。