基本含义及两个实例,均可在VS中运行。
前言
回调函数的定义是(根据百度百科):是一个通过函数指针调用的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用所指向函数的时候,就称为回调函数。C语言中的函数回调主要是通过函数指针来完成的,这给程序的开发提供了很大的灵活性。
一、回调函数的含义
C语言程序中的回调函数要包括三个部分:主函数main()、中间函数library()、回调函数callback()。过程:main()在调用library()的时候,通过参数给library()传递了F1函数的指针(地址);在library()执行的时候,调用了F1函数;这就是回调(callback),F1就是回调函数。
二、两个应用举例
1. 改写前的程序1
纸上得来终觉浅,通过语言叙述很难理解回调函数的用法。下面简单的通过函数调用方式实现的一个四则运算计算器,实现了加减乘除的功能,可以看出程序中冗杂的内容太多,进行4+6运算,运行后的结果为:
代码如下(运行时请自行添加头文件)
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int mul(int x, int y)
{
return x * y;
}
int div(int x, int y)
{
return x / y;
}
void menu()
{
printf("****************************\n");
printf("**** 1.add 2.sub ****\n");
printf("**** 3.mul 4.div ****\n");
printf("**** 0.exit ****\n");
printf("****************************\n");
}
int main()
{
int input = 0;
do {
menu();
printf("请选择 :");
scanf_s("%d", &input);
switch (input)
{
int x = 0;
int y = 0;
int result = 0;
case 1:
printf("请输入两个操作数:");
scanf_s("%d %d", &x, &y);
result = add(x, y);
printf("%d\n", result);
break;
case 2:
printf("请输入两个操作数:");
scanf_s("%d %d", &x, &y);
result = sub(x, y);
printf("%d\n", result);
break;
case 3:
printf("请输入两个操作数:");
scanf_s("%d %d", &x, &y);
result = mul(x, y);
printf("%d\n", result);
break;
case 4:
printf("请输入两个操作数:");
scanf_s("%d %d", &x, &y);
result = div(x, y);
printf("%d\n", result);
break;
case 0:
printf("退出");
break;
default:
printf("选择错误,请重新选择。\n");
break;
}
} while (input);
return 0;
}
2.用回调函数的方式改写后1
用回调函数的方式改写后,函数不仅代码量精简了,而且需要添加功能的时候也方便了许多。代码如下(示例):
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int mul(int x, int y)
{
return x * y;
}
int div(int x, int y)
{
return x / y;
}
void menu()
{
printf("****************************\n");
printf("**** 1.add 2.sub ****\n");
printf("**** 3.mul 4.div ****\n");
printf("**** 0.exit ****\n");
printf("****************************\n");
}
int calc(int (*pf)(int, int)) //中间函数
{
int x = 0;
int y = 0;
printf("请输入两个操作数:");
scanf_s("%d %d", &x, &y);
printf("%d\n", pf(x,y)); //pf指向了对应的操作函数
}
int main()
{
int input = 0;
do {
menu();
printf("请选择 :");
scanf_s("%d", &input);
switch (input)
{
int result = 0;
case 1:
result = calc(add); //将相应的操作函数地址传过去,故calc用函数指针接收
break;
case 2:
result = calc(sub);
break;
case 3:
result = calc(mul);
break;
case 4:
result = calc(div);
break;
case 0:
printf("退出");
break;
default:
printf("选择错误,请重新选择。\n");
break;
}
} while (input);
return 0;
}
3.模拟Qsort函数的排序实现2
给一个数组arr[10]进行升序排序,模拟Qsort的方式,自行编写了一个b_sort()函数,为了使改程序可以排序任一格式的数据,所以用void*接传参。
void swap(char* buf1, char* buf2, int width)
{
for (int i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void b_sort(void* base, int sz, int width, int (*cmp)(const void* e1, const void* e2))
{
for (int i = 0; i < sz - 1; i++) //排序的趟数
{
for (int j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
//交换
swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
int cmp_int(const void* e1, const void* e2) //比较函数 返回int
{
return *(int*)e1 - *(int*)e2;
}
void print_arr(int arr[10], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void main()
{
int arr[10] = { 0,3,4,1,2,5,6,7,9,8 };
int sz = sizeof(arr) / sizeof(arr[0]);
b_sort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
总结
简单地总结了初学回调函数的过程。