目录
思维导图:
回调函数
qsort函数介绍
模拟实现qsort
写在最后:
思维导图:
回调函数
什么是回调函数?
回调函数是一个通过函数指针调用的函数。
将一个函数指针作为参数传递给一个函数,当这个指针被用来调用所指向函数时,
我们就将此称为回调函数。
在举例之前,我们先学习一个C语言的库函数qsort。
qsort函数介绍
qsort函数是一个排序函数,可以帮助我们排序。
我们为什么要学习这样一个函数呢?
我们对一个整形数组进行排序:
例:
#include <stdio.h>
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;
}
这个库函数需要调用的头文件是:<stdlib.h>
以及各个参数的不同意思:
#include <stdio.h>
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 <stdio.h>
#include <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
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 <stdio.h>
#include <stdlib.h>
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岁
写在最后:
以上就是本篇文章的内容了,感谢你的阅读。
如果喜欢本文的话,欢迎点赞和评论,写下你的见解。
如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。
之后我还会输出更多高质量内容,欢迎收看。