
🎉个人主页: 缘三水的博客
❄专栏传送门:C语言专栏(新手向)
🎀人生格言:行动是迷茫的最好解药
🚀个人介绍:

往篇回顾
文章目录
正文开始
(一)回调函数
定义
通过函数指针变量 中存放的地址,调用指向的函数
被调用的函数就被称为回调函数
示例

特点:回调函数不是由该函数直接调用,而是在另一方中通过函数指针间接调用
使用回调函数示例
对上一章中的计算器实现,我们还有一种优化方法,就是利用回调函数
c
void menu()
{
printf("*********************\n");
printf("***1.add 2.sub***\n");
printf("***3.mul 4.div***\n");
printf("***0.exit ***\n");
printf("*********************\n");
}
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x * y;
}
int Div(int x, int y)
{
return x / y;
}
void Calc(int (*pf)(int, int))
{
int x = 0;
int y = 0;
int r = 0;
printf("请输入两个操作数");
scanf("%d %d", &x, &y);
r = pf(x, y);
printf("%d\n", r);
}
int main()
{
int input = 0;
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
Calc(Add);
break;
case 2:
Calc(Sub);
break;
case 3:
Calc(Mul);
break;
case 4:
Calc(Div);
break;
case 0:
printf("退出计算器\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
对函数Calc
函数的参数是函数指针,可以接收不同的函数地址
接收的地址不同,调用的函数不同
这个Calc函数就能根据参数的不同完成不同的功能
(二)qsort函数
定义
qsort 是quick sort 简称,名为快速排序
qsort是C语言中提供的一个排序函数
是基于快速排序算法思想的一种排序算法
优势
- 现成的排序算法
- 效率 比冒泡排序高
- qsort可以实现任意类型数据的排序
这里提供C++官网对qsort函数的解释
qsort函数
qsort对应头文件是 #include <stdlib.h>

qsort函数有四个参数
我们来对四个参数进行一一解释
c
void qsort (void* base, //指针,指向了被排序数组的第一个元素
size_t num,//被排序数组的元素个数
size_t size,//被排序数组的元素的大小,单位是字节
int (*compar)(const void*,const void*));//函数指针,指向的函数是比较被排序数组中两个元素的比较方法
因为不同的数据类型,排序的标准不同
所以最后一个参数是使用qsort函数的用户
根据自己需要,编写一个比较函数,比较两个元素的方法

而对于最后一个参数函数指针 指向的函数返回值类型为int 的解释
如果要排为升序
当比较两个元素时
前面的元素比后面小 ,则返回-1
前面的元素与后面一样大 ,则返回0
前面的元素比后面大 ,则返回1
使用示例1
给一个整型数组排序

使用示例2
给一个结构体数组排序
按年龄给结构体升序排序

结果

拓展
结构体成员访问操作符 ->
语法格式
结构体指针 -> 成员名
使用示例

特点:通过结构体指针 间接访问结构体成员变量
点操作符. 直接访问结构体成员变量
因此,比较函数还能这么写
c
int cmp_stu_by_age(const void* p1, const void* p2)//比较函数
{
//按年龄大小升序排结构体
//return (*(struct stu*)p1).age - (*(struct stu*)p2).age;//直接访问
return ((struct stu*)p1)->age - ((struct stu*)p2)->age;//间接访问
}
使用实例3
按结构体成员名字比较
拓展 strcmp函数
这里的名字是字符串
比较不能使用关系运算符
字符串的比较需要用到strcmp函数
这里提供C++官网对strcmp函数的解释
strcmp函数

strcmp函数比较字符串原理
是根据同一位上的字符对应ASCII码值 的大小比较
不是比较字符串的长度
strcmp函数头文件
c
#include <string.h>
示例3代码实现

结果

(三)模拟实现qsort函数
我们能不能根据qsort函数为原型,自己封装一个功能相同 的函数呢?
下面是根据冒泡排序原理编写的代码
示例
排序整型数组
c
void print_arr(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int cmp_int(void* p1, void* p2)
{
return *(int*)p1 - *(int*)p2;
}
void Swap(char* buf1, char* buf2, size_t width)
{
char tmp = 0;
for (int i = 0; i < width; i++)
{
tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble2_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* p1, const void* p2))
{
for (int i = 0; i < sz - 1; i++)
{
for (int 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);
}
}
}
}
int main()
{
int arr[] = { 2,4,6,8,0,1,3,5,7,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
print_arr(arr, sz);
bubble2_sort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
return 0;
}
示例
按照名字排序结构体数组
c
struct stu//定义结构体
{
char name[30];
int age;
};
void print_arr(struct stu arr[], int sz)//打印函数
{
for (int i = 0; i < sz; i++)
{
printf("%s : %d\n", arr[i].name, arr[i].age);
}
printf("\n");
}
int cmp_stu_by_name(const void* p1, const void* p2)//比较函数
{
//按名字升序排结构体
return strcmp(((struct stu*)p1)->name, ((struct stu*)p2)->name);
}
void Swap(char* buf1, char* buf2, size_t width)
{
char tmp = 0;
for (int i = 0; i < width; i++)
{
tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble2_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* p1, const void* p2))
{
for (int i = 0; i < sz - 1; i++)
{
for (int 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);
}
}
}
}
int main()
{
struct stu arr[] = { {"zhangsan",28},{"lisi",18},{"wangwu",38} };
int sz = sizeof(arr) / sizeof(arr[0]);
print_arr(arr, sz);
bubble2_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
print_arr(arr, sz);
return 0;
}
总结
这篇文章我们详细介绍了回调函数,qsort函数以及模拟实现qsort函数,希望能对你有帮助
有错误的地方希望可以得到大佬的指正
最后不要吝啬你的点赞,收藏和评论!!!
感谢你的观看