C语言:深入理解指针(5)
1.回调函数
回调函数就是⼀个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被用来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。在上一讲中我们说过在学习指针函数前我们可以通过 switch 语句来写这个问题,但是这样 case 语句中就会有很多冗余的内容,通过回调函数我们就可以解决这个问题,代码和执行结果如下:
#include 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 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 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;}