目录
一.回调函数
先来了解一下回调函数的机制
回调函数就是一个函数通过函数指针调用的函数,如果你把函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就称这个函数为回调函数
回调函数不是由该函数的实现方直接调用,而是提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者,当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。
上一篇里面计算器的实现使用了函数指针数组的方法
我们来看一看用回调函数的机制怎么实现它。
回调函数机制图示:
二.qsort函数排序法
引入:
还记得我们之前学习的冒泡函数吗?
冒泡函数排序源代码:
//冒泡函数
void Bubble_sort(int arr[], int sz)
{
int i = 0;
int j = 0;
for (i = 0; i < sz - 1; i++)
{
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[10] = { 9, 8, 7, 6, 4, 5, 3, 2, 1, 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
所以,我们来看一下qsort函数。
先来了解一下这个函数的原型是什么样子的:
void qsort(
void* base,
size_t num,
size_t size,
int(*compare)(const void *e1, const void *e2) //这个函数需要我们自己实现
);//它有四个参数,一起向下面看~
那都是什么意思呢?
打开cplusplus.com搜索查阅一下
我们挑重要的内容读:
(我们在这里先学会使用qsort函数,先不考虑qsort函数内部的机制是怎么运行的。)
写代码感受一下qsort函数的实际应用
“void*”的解释
1.void*可以接受任意类型的地址
2.void*不能进行解引用操作
3.void*不能进行加减整数操作
再来理解一下这段代码:
理解之后,我们再来试试能不能对结构体排个序呢?
一起来验证一下:
三.通用冒泡排序法的实现以及qsort函数的模拟实现
前面我们说,常规的冒泡函数是有局限性的,我要是想排序个浮点型,结构体类型,该怎么排序呢?
接下来我们一起来看看。
//定义一个结构体
struct stu
{
char name[10];
int age;
};
//
//根据结构体名字来排序
int cmp_struct_by_name(const void *e1 , const void *e2)
{
return strcmp( ((struct stu*)e1) -> name , ((struct stu*)e2) -> name ); //字符串的比较需要用到strcmp函数
}
//根据结构体年龄来排序
int cmp_struct_by_age(const void *e1, const void *e2)
{
return ((struct stu*)e1)->age - ((struct stu*)e2)->age; //字符串的比较需要用到strcmp函数
}
//浮点型数组排序
int cmp_float(const void *e1, const void *e2)
{
return *(float*)e1 - *(float*)e2;
}
//交换
void Swap(char *buf1, char *buf2 , int width) //char能不能写成int呢? 不可以
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
//通用版冒泡排序
void bubble_sort(void *base, int sz, int width, int(*cmp)(const void *e1, const void *e2))
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if ( cmp( (char*)base + j*width, (char*)base + (j + 1)*width) > 0 ) //要升序排列
{
Swap( (char*)base + j * width, (char*)base + (j + 1)*width , width );
}
}
}
}
void test1()
{
struct stu s[3] = { { "zhangsan", 20 }, { "lisi", 30 }, { "wangwu", 10 } };
int sz = sizeof(s) / sizeof(s[0]);
bubble_sort(s, 3, sizeof(stu), cmp_struct_by_name);
for (int i = 0; i < 3; i++)
{
printf("%s ", s[i].name);
}
}
void test2()
{
float p[] = { 9.0, 8.0, 7.0, 6.0, 5.0, 4.0 }; //浮点型数组
int sz = sizeof(p) / sizeof(p[0]);
bubble_sort(p, sz, sizeof(p[0]), cmp_float);
for (int i = 0; i < sz; i++)
{
printf("%f ", p[i]);
}
}
int main()
{
//test1();
test2();
return 0;
}
这里的代码还加入了一个结构体的比较,大家可以看一看
去自己的编译器里面跑一跑,验证一下,一定要去自己学习验证一下。
套娃结束!!