思维导图:
回调函数
什么是回调函数?
回调函数是一个通过函数指针调用的函数。
将一个函数指针作为参数传递给一个函数,当这个指针被用来调用所指向函数时,
我们就将此称为回调函数。
在举例之前,我们先学习一个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 < sz - 1 - i; j++) { if (arr[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 < sz; i++) { printf("%s %d岁\n", (&s[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 < sz - 1 - i; j++) { //这里运用了回调函数,在冒泡排序函数里调用cmp_int函数,并判断 //这里判断函数返回的值大于零就进入语句,排序后是升序数组 if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 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 < sz - 1 - i; j++) { //这里运用了回调函数,在冒泡排序函数里调用cmp_int函数,并判断 //这里判断函数返回的值大于零就进入语句,排序后是升序数组 if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 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 < sz; i++) { printf("%s %d岁\n", (&s[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岁
写在最后:
以上就是本篇文章的内容了,感谢你的阅读。
如果喜欢本文的话,欢迎点赞和评论,写下你的见解。
如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。
之后我还会输出更多高质量内容,欢迎收看。