目录

思维导图:

回调函数

qsort函数介绍

模拟实现qsort

写在最后:


思维导图:

回调函数

什么是回调函数?

回调函数是一个通过函数指针调用的函数。

将一个函数指针作为参数传递给一个函数,当这个指针被用来调用所指向函数时,

我们就将此称为回调函数。

在举例之前,我们先学习一个C语言的库函数qsort。

qsort函数介绍

qsort函数是一个排序函数,可以帮助我们排序。

我们为什么要学习这样一个函数呢?

我们对一个整形数组进行排序:

例:

#include void print(int arr[], int sz){int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}}void bubble_sort(int arr[], int sz){int i = 0;for (i = 0; i < sz - 1; i++){int j = 0;for (j = 0; j  arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}}void test(){int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);//冒泡排序print(arr, sz);//打印}int main(){test();//分装函数return 0;}

输出:

输出:0 1 2 3 4 5 6 7 8 9

但是如果我们想对一个结构体进行排序,冒泡排序就承担不了这个任务了,

(不止结构体,像浮点数啊,字符数组啊,冒泡排序都无法工作)

这个时候,我们就能使用qsort函数帮我们排序。

我们可以通过cplusplus学习一下这个函数:

通过阅读介绍,我们得知qsort的功能:

对数组中由指针指向的元素进行排序,根据每个元素字节长度,使用函数确定顺序。

此函数使用的快速排序算法通过调用指定的函数来比较元素,并将指向它们的指针作为参数。

该函数不返回任何值,但通过重新排序数组的元素来修改指向的数组的内容。

以及使用该函数需要传递的参数:

int main(){void qsort(void* base, size_t num, size_t size,int (*compar)(const void*, const void*));//一个指针,两个无符号整数,一个函数指针return 0;}

这个库函数需要调用的头文件是:

以及各个参数的不同意思:

#include int main(){void qsort(void* base, size_t num, size_t size,int (*compar)(const void*, const void*));//void*base是指向要排序的数组的第一个对象的指针,转换为void*类型//size_t num是数组中的元素数//size_t size是数组中每个元素的大小(以字节为单位)//int (*compar)(const void*, const void*))是指向比较两个元素的函数的指针return 0;}

这样,我们就能使用qsort函数帮助我们排序了:

例:

#include #include struct Stu{char name[20];int age;};int cmp_stu_by_age(const void* e1, const void* e2){return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;//如果e1 > e2则返回>O的数//如果e1 = e2则返回0//如果e1 < e2则返回<0的数}void print(struct Stu* s, int sz){int i = 0;for (i = 0; i name,(&s[i])->age);}}void test(){struct Stu s[3] = { {"张三",20}, {"李四", 50}, {"王五", 33} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);//排序print(s, sz);//打印函数}int main(){test();//分装函数return 0;}

输出:

输出:张三 20岁王五 33岁李四 50岁

利用qsort函数,我们成功给结构体排序了。

模拟实现qsort

在模拟实现qsort时,我们就要用到回调函数的思想:

例:

#include #include int cmp_int(const void* e1, const void* e2){return *(int*)e1 - *(int*)e2;//如果e1 > e2则返回>O的数//如果e1 = e2则返回0//如果e1 < e2则返回<0的数}//通过交换每个字节的形式,以达成交换两个数的值的目的void Swap(char* buf1, char* buf2, int width){int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}}//这里将cmp_int函数的指针传参void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2)){//趟数size_t i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序的过程size_t j = 0;for (j = 0; j  0){//交换Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}}void print(int arr[], int sz){int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}}void test(){int arr[] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);print(arr, sz);//打印函数}int main(){test();//分装函数return 0;}

输出:

输出:0 1 2 3 4 5 6 7 8 9

再用它来排序一下结构体数组也是可以的:

例:

#include #include struct Stu{char name[20];int age;};int cmp_stu_by_age(const void* e1, const void* e2){return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;//如果e1 > e2则返回>O的数//如果e1 = e2则返回0//如果e1 < e2则返回<0的数}//通过交换每个字节的形式,以达成交换两个数的值的目的void Swap(char* buf1, char* buf2, int width){int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}}//这里将cmp_int函数的指针传参void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2)){//趟数size_t i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序的过程size_t j = 0;for (j = 0; j  0){//交换Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}}void print(struct Stu* s, int sz){int i = 0;for (i = 0; i name,(&s[i])->age);}}void test(){struct Stu s[3] = { {"张三",20}, {"李四", 50}, {"王五", 33} };int sz = sizeof(s) / sizeof(s[0]);bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_age);print(s, sz);//打印函数}int main(){test();//分装函数return 0;}

输出:

输出:张三 20岁王五 33岁李四 50岁

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果喜欢本文的话,欢迎点赞和评论,写下你的见解。

如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。

之后我还会输出更多高质量内容,欢迎收看。