目录
思维导图:
回调函数
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岁
写在最后:
以上就是本篇文章的内容了,感谢你的阅读。
如果喜欢本文的话,欢迎点赞和评论,写下你的见解。
如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。
之后我还会输出更多高质量内容,欢迎收看。