首先,回调函数的定义就是指通过函数指针调用的函数。之前我们讲过函数指针是指向函数的指针。其表示形式为:
void(*)()
那么我们通过一个简单的代码来实现回调函数:
void test(){
printf("CSDN\n");
}
void print(void(*p)()){
if(1)
p();
}
int main(){
print(test);
return 0;
}
这时,其中print(test)就是回调函数,他是通过取出test函数的地址放到一个函数指针中再进行调用。
回调函数的应用也会缩短代码量,也就是代码的冗余量。比如说我们实现简易的计算器,那么进入switch中后每一次选择运算方式都要求输入两个操作数,重复的代码量过多,那么此时我们就可以使用回调函数,将重复的代码放到一个无返回值的函数中去,然后将运算方式的代码的地址传过去,那么这个无返回值的函数的形参就是函数指针。
下面我们实现一下这个代码:
void menu(){
printf("1.Add\n");
printf("2.Sub\n");
printf("3.Mul\n");
printf("4.Div\n");
}
void Add(int x,int y){
return x+y;
}
void Sub(int x,int y){
return x-y;
}
void Mul(int x,int y){
return x*y;
}
void Div(int x,int y){
return x/y;
}
void calc(int (*p)(int,int)){
int x=0,y=0,ret=0;
printf("请输入两个操作数:");
scanf("%d %d",&x,&y);
ret=p(x,y);
printf("ret=%d",ret);
}
int main(){
int input=0;
do{
menu();
scanf("%d",&input);
switch(input){
case 1:calc(Add);break;
case 2:calc(Sub);break;
case 3:calc(Mul);break;
case 4:calc(Div);break;
}
}while(input);
return 0;
}
其中calc函数就是我们说的回调函数,它的形参是int(*p)(int,int)的函数指针,传过去的也是test函数的地址。这里说一下,对于函数来说,test和&test都可表示该函数的地址。所以这样写大大减少了代码的冗余量,使得代码更简化。
那么结合我们之前在函数指针中所讲的函数指针数组,可以知道,这个代码的switch函数还可以再简化成函数指针数组:
int main(){
int input=0;
int (*pf[5])(int,int)={0,calc(Add),calc(Sub),calc(Mul),calc(Div)};
do{
menu();
scanf("%d",&input);
pf[input](int,int);
}while(input);
return 0;
}
可以看出,运用了函数指针数组后的代码量更少了。