深入理解指针(4)

目录

1. 回调函数是什么?

2. qsort使用举例

 3. qsort函数的模拟实现


1. 回调函数是什么?

回调函数就是⼀个通过函数指针调用的函数。( 如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被用来调用其所指向的函数 时,被调用的函数就是回调函数。)

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的⼀方调用的,用于对该事件或条件进行响应。 深入理解指针(3)中我们写的计算器的实现的代码中,红色框中的代码是重复出现的,其中执行计算的逻辑是区别的,会导致输入输出操作冗余。可是有没有办法,简化⼀些呢?当然有。

因为红色框中的代码,只有调用函数的逻辑是有差异的,我们可以把调用的函数的地址以参数的形式传递过去,使用函数指针接收,函数指针指向什么函数就调用什么函数,这里其实使用的就是回调函数的功能。

代码一:(不使用回调函数)

#define _crt_secure_no_warnings
#include <stdio.h>
#pragma warning(disable:4996)void menu(void)
{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;
}int main()
{int x = 0;int y = 0;int input = 0;int(*p[5]) (int x, int y) = { 0,ADD,SUB,MUL,DIV };do{menu();printf("请选择你想要实现的功能>");scanf("%d", &input);switch (input){case 1:{printf("请输入操作数>");scanf("%d,%d", &x, &y);int ret = p[input](x, y);// 加法printf("%d\n", ret);break;}case 2:{printf("请输入操作数>");int x = 0;int y = 0;scanf("%d,%d", &x, &y);int ret = p[input](x, y);// 减法printf("%d\n", ret);break;}case 3:{printf("请输入操作数>");int x = 0;int y = 0;scanf("%d,%d", &x, &y);int ret = p[input](x, y);// 乘法printf("%d\n", ret);break;}case 4:{printf("请输入操作数>");int x = 0;int y = 0;scanf("%d,%d", &x, &y);int ret = p[input](x, y); // 除法printf("%d\n", ret);break;}case 0:{printf("退出计算器!\n");break;}default:{printf("输入错误,请重新输入!\n");break;}}} while (input);return 0;
}

代码二:(使用回调函数)

#define _crt_secure_no_warnings
#include <stdio.h>
#pragma warning(disable:4996)void menu(void)
{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;
}int main()
{int x = 0;int y = 0;int input = 0;int(*p[5]) (int x, int y) = { 0,ADD,SUB,MUL,DIV };do{menu();printf("请选择你想要实现的功能>");scanf("%d", &input);switch (input){case 1:{printf("请输入操作数>");scanf("%d,%d", &x, &y);int ret = p[input](x, y);// 加法printf("%d\n", ret);break;}case 2:{printf("请输入操作数>");int x = 0;int y = 0;scanf("%d,%d", &x, &y);int ret = p[input](x, y);// 减法printf("%d\n", ret);break;}case 3:{printf("请输入操作数>");int x = 0;int y = 0;scanf("%d,%d", &x, &y);int ret = p[input](x, y);// 乘法printf("%d\n", ret);break;}case 4:{printf("请输入操作数>");int x = 0;int y = 0;scanf("%d,%d", &x, &y);int ret = p[input](x, y); // 除法printf("%d\n", ret);break;}case 0:{printf("退出计算器!\n");break;}default:{printf("输入错误,请重新输入!\n");break;}}} while (input);return 0;
}

2. qsort使用举例

2.1 使用qsort函数排序整型数据

int cmp_int(void const* p1, void const* p2)
{return *(int*)p1 - *(int*)p2;
}int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;int len = sizeof(arr) / sizeof(arr[0]);qsort(arr, len, sizeof(arr[0]),cmp_int);for (i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;
}

2.2 使用qsort排序结构数据

typedef struct stu
{char name[20];// 名字int age;// 年龄
}stu;int cmp_age(void const* e1, void const* e2)
{return ((stu*)e1)->age - ((stu*)e2)->age;// 按照年龄从小到大判断
}int main()
{stu s[] = { {"zhangsan",19},{"lisi",18},{"wangwu",20} };int len = sizeof(s) / sizeof(s[0]);qsort(s, len, sizeof(s[0]), cmp_age);for (int i = 0; i < len; i++){printf("%s %d\n",s[i].name, s[i].age);}return 0;
}

由此可见,上面这个代码是将年龄由低到高进行排序。

typedef struct stu
{char name[20];int age;}stu;int cmp_name(void const* e1, void const* e2)
{return strcmp((((stu*)e1)->name),(((stu*)e2)->name));
}int main()
{stu s[] = { {"zhangsan",19},{"lisi",18},{"wangwu",20} };int len = sizeof(s) / sizeof(s[0]);qsort(s, len, sizeof(s[0]), cmp_name);for (int i = 0; i < len; i++){printf("%s %d\n", s[i].name, s[i].age);}return 0;
}

这个则是由名字从小到大进行排序的。

 3. qsort函数的模拟实现

int cmp_int(const void* e1, const void* e2)
{return *((int*)e1) - *((int*)e2);
}void swap(void* e1, void* e2,int size)
{int i = 0;for (i = 0; i < size; i++){char temp = *((char*)e1+ i);*((char*)e1+i) = *((char*)e2+i);*((char*)e2 + i) = temp;}
}void Bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{int i = 0;int j = 0;for (i = 0; i < count - 1; i++){for (j = 0; j < count - i - 1; j++){if (cmp((char*)base + size * j, (char*)base + size * (j + 1)) > 0){swap((char*)base + j * size, (char*)base + (j + 1) * size,size);}}}}int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;int len = sizeof(arr) / sizeof(arr[0]);Bubble(arr, len, sizeof(arr[0]), cmp_int);for (i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;
}

到这里这篇博客就结束咯,感谢大家的阅读!

具体qsort函数的使用详解会专门出个博客,敬请期待~