1.回调函数
回调函数就是⼀个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被用来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。在上一讲中我们说过在学习指针函数前我们可以通过 switch 语句来写这个问题,但是这样 case 语句中就会有很多冗余的内容,通过回调函数我们就可以解决这个问题,代码和执行结果如下:
#include <stdio.h>
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 Print()
{
printf("******************************\n");
printf("******1.加法****2.减法********\n");
printf("******3.乘法****4.除法********\n");
printf("************0.退出************\n");
printf("******************************\n");
printf("请选择:");
}
int calcu(int(*p)(int, int))
{
printf("输入操作数:");
int ans = 0;
int x, y;
scanf("%d %d", &x, &y);
ans = p(x, y);
printf("%d\n", ans);
}
int main()
{
int input = 0;
do
{
Print();
scanf("%d", &input);
switch (input)
{
case 1:calcu(add);break;
case 2:calcu(sub);break;
case 3:calcu(mul);break;
case 4:calcu(div);break;
case 0:printf("退出计算器");break;
default:printf("输入错误,重新输入\n");break;
}
} while (input);
return 0;
}

区别是我们多了一个 calcu 函数,我们把调⽤的函数的地址以参数的形式传递过去,使⽤函数指针接收,函数指针指向什么函数就调用什么函数,这⾥其实使⽤的就是回调函数的功能。
2. qsort 使用举例
2.1 使用 qsort 函数排序整型数据
qsort函数是一个库函数,这个库函数是用来排序的,是基于快速排序算法实现的一个库函数,这个函数可以用来排序任意类型的数据。
之前的学习中我们学习了冒泡排序算法,但之前写的那个算法是用来排序整型数组的,但却不能用来排序浮点型和结构体数据,而是只能排序固定类型的数据。下来让我们来学习一下 qsort 函数。
void qsort(void *base, //指向待排序数组的第一个元素,可以接受任意类型的数据
size_t num, //待排序数组的元素个数
size_t size, //待排序数组中元素的大小,单位是字节
int (*compar)(const void *p1, const void *p2)
//compar是一个函数指针,这个指针可以接受一个函数地址
//这个函数是使用qsort函数的人设计的,这个函数用来比较两个数组元素的大小
);
在这里我们约定当 p1 指向的元素大于 p2 指向的元素时,因该返回一个大于 0 的数字;当 p1 指向的元素等于 p2 指向的元素时,返回 0,当 p1 指向的元素小于 p2 指向的元素时,返回一个小于 0 的数字。

如图就是一个通过 qsort 函数实现排序的过程。 注意:qsort 默认是升序的。
2.2 使用 qsort 函数排序结构数据
注意,两个字符转比较大小不是比长度,而是比较对应位置上字符的大小。

3. qsort 函数的模拟实现
使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。
代码和执行结果如下:
#include <stdio.h>
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
void _swap(void* p1, void* p2, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *((char*)p1 + i);
*((char*)p1 + i) = *((char*)p2 + i);
*((char*)p2 + i) = tmp;
}
}
void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{
int i = 0;
int j = 0;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - i - 1; j++)
{
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
_swap((char*)base + j * size, (char*)base + (j + 1) * size,
size);
}
}
}
}
int main()
{
int arr[] = { 1,3,2,4,5,7,6,8,9,0 };
int i = 0;
bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
