苏州网站建站推广,电商网站建设费用价格,电商网站运营,推广代理文章目录 1.回调函数概念举例 2.qsort函数qsort的使用 3.通过冒泡排序来模拟qsort函数排序int类型排序结构体类型 这是指针最后一篇了喔#xff0c;完结撒花 ! 前三篇#xff1a; 浅谈指针#xff08;1#xff09;http://t.csdnimg.cn/JTRjW 浅谈指针#xff08;2#xf… 文章目录 1.回调函数概念举例 2.qsort函数qsort的使用 3.通过冒泡排序来模拟qsort函数排序int类型排序结构体类型 这是指针最后一篇了喔完结撒花 ! 前三篇 浅谈指针1http://t.csdnimg.cn/JTRjW 浅谈指针2http://t.csdnimg.cn/1aPkr 浅谈指针3http://t.csdnimg.cn/TndpD
1.回调函数
概念 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针地址作为参数传递给另⼀个函数当这个指针被⽤来调⽤其所指向的函数时被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的⽤于对该事件或条件进⾏响应。通过回调函数能够是代码简便。 如 实现加法
int add(int x, int y) {return x y;
}
void su(int (*p)(int, int)) {int a10, b20;printf(%d, p(a, b));
}int main() {su(add);return 0;
}注要通过函数指针来接收函数地址
举例
通过回调函数实现计算器 1.选择界面 2.实现加、减。乘、除函数 3.一个接收这四个函数地址的函数 实现
#include stdio.h
int add(int a, int b)//加
{return a b;
}
int sub(int a, int b)//减
{return a - b;
}
int mul(int a, int b)//乘
{return a * b;
}
int div(int a, int b)//除
{return a / b;
}
void calc(int(*pf)(int, int))//接收函数地址的函数
{int ret 0;int x, y;printf(输⼊操作数);scanf(%d %d, x, y);ret pf(x, y);//调用printf(ret %d\n, ret);
}
int main()
{int input 1;do{printf(******************printf( 1:add printf( 3:mul printf(******************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}虽然说现在看起来还是那么多那是因为这里只是四个函数而已如果加上其他的计算功能呢。这样就能够大大减少代码量了
2.qsort函数 对所指向的数组元素进行排序每个元素的长度为字节使用函数确定顺序。 此函数使用的排序算法通过调用指定的函数来比较元素对并将指向元素的指针作为参数。 该函数不返回任何值而是通过对数组的元素进行重新排序来修改所指向的数组的内容. 注意的是 compar函数的创建的格式和 qsort的一样 int (*compar)(const void*,const void*));//这个是自己创建的
qsort的使用
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));我们来实现一个整形排序
int hanshu(const void* p1,const void* p2) {//这里要按照qsort中的函数参数类型来写
//int (*compar)(const void*,const void*));return (*((int*)p1) - *((int*)p2));//返回-上面有解释 (int*)p1--强制转换为int类型指针
}
int main() {int arr[] { 5,3,2,4,1 };int zs sizeof(arr) / sizeof(arr[0]);//数组大小qsort(arr, zs, sizeof(arr[0]), hanshu);//按照规则填入 sizeof(arr[0])一个元素占多少字节for (int i 0; i zs; i)//打印printf(%d , arr[i]);return 0;
}我们来看看运行结果 成功完成排序 那么我们再来试一下结构体
struct sl {//构建结构体char arr[20];int a;
};
int hanshu(void* p1, void* p2) {return strcmp(((struct sl*)p1)-arr,((struct sl*)p2)-arr);//判断结构体中arr的大小//strcmp--用于比较两个字符大小 (struct sl*)p1强制类型转换成结构体类型指针
}int main() {struct sl s[] { {zhangsan,18} ,{lisi,19}, {wanwu,12}};int zs sizeof(s) / sizeof(s[0]);//计算大小qsort(s, zs, sizeof(s[0]), hanshu);//进行排序for (int i 0; i zs; i)//打印printf(%s %d\n, s[i].arr,s[i].a);//打印结构体return 0;
}运行结果 总结qsort函数能够实现多种数据的排序 3.通过冒泡排序来模拟qsort函数
接下来我们通过冒泡排序来模拟qsort函数 不懂冒泡排序的可以看看这个哦冒泡排序http://t.csdnimg.cn/0uNZH 1.一般的冒泡排序只能用来排序整数类型我们想要通过冒泡排序的方式来模拟qsort函数那么我们创造的冒泡函数的参数类型我们也和qsort和参数类型一样。 c void maopao (void* base, size_t num, size_t size, int (*compar)(const void*,const void*)); 2.我们比大小时要改变传递给比大小函数的参数因为我们不知道从主函数传过来的是什么类型数据如有char、short、int等类型。那么怎么改变呢我们可以将从主函数传过来的数据进行强制类型转换转为char* 类型由于char类型的为1字节满足最小的数据类型转化为char * 后再通过从主函数传过来的的类型宽度和在循环中的变量来改变指针指向的位置这样就可以控制传递给比大小函数的指针了。 3.交换时传递的参数和如何交换跟比大小函数一样不知道从主函数传过来的数据类型是什么那么怎么样设置参数和交换呢我们可以通过一个字节一个字节来交换数据我们可以通过传递从主函数传过来的数据类型宽度来控制循环次数那样不管是什么类型都可以交换了那么我们还是将从主函数传过来的强制类型转换为char 再传过去给交换函数进行交换。 排序int类型
代码实现
int cmp(const void* p1, const void* p2) {//比大小因为返回类型为 int 所以强行转为int*再解引用return (*(int*)p1 - *(int*)p2);
}void huan(char* p1,char* p2, int ws) {//交换函数ws为类型长度一个字节一个字节换int i 0;for (i 0; i ws; i) {//循环的次数和我们比较类型的宽度有关char te *(p1 i);*(p1i) *(p2i);*(p2i) te;}
}
void maopao(void* p, int zs, int ws, int (*cmp)(const void*,const void*)) {//冒泡模拟的qsort函数传入参数和qsort函数一样int i 0;for (i 0; i zs - 1; i) {//正常冒泡排序的流程走n-1趟int j 0;for (j 0; j zs - 1 - i; j) {//前后对比if (cmp((char*)p ws * j, (char*)p ws * (j 1)) 0) {//传给cmp函数的参数先转为char*类型再通过变量j和宽度ws就可以找到正确的指针phuan((char*)p ws * j, (char*)p ws * (j 1), ws);//交换//参数先转为char*类型再通过变量j和宽度ws就可以找到正确的指针p}}}}
void dayin1(int arr[], int zs) {//打印for (int i 0; i zs; i)printf(%d , arr[i]);printf(\n);
}int main() {int arr[10] { 2,3,6,7,1,4,9,5,0,8 };int zs sizeof(arr) / sizeof(arr[0]);//求数组元素个数dayin1(arr, zs);//打印原来的数组maopao(arr, zs, sizeof(arr[0]), cmp);//sizeof(arr[0])元素宽度dayin1(arr, zs);printf(\n);return 0;
}运行结果 成功进行排序了 交换过程图解
排序结构体类型
代码实现
struct sl {//创建结构体char r[20];//名字int b;//年龄
};
int cmp(const void* p1, const void* p2) {return strcmp(((struct sl*)p1)-r, ((struct sl*)p2)-r);//对结构体中的名字比大小
}//strcmp函数 用于字符串比大小void huan(char* p1, char* p2, int ws) {//交换函数ws为类型长度一个字节一个字节换int i 0;for (i 0; i ws; i) {//循环的次数和我们比较类型的宽度有关char te *(p1 i);*(p1 i) *(p2 i);*(p2 i) te;}
}
void maopao(void* p, int zs, int ws, int (*cmp)(const void*, const void*)) {//冒泡模拟的qsort函数传入参数和qsort函数一样int i 0;for (i 0; i zs - 1; i) {//正常冒泡排序的流程走n-1趟int j 0;for (j 0; j zs - 1 - i; j) {//前后对比if (cmp((char*)p ws * j, (char*)p ws * (j 1)) 0) {//传给cmp函数的参数先转为char*类型再通过变量j和宽度ws就可以找到正确的指针phuan((char*)p ws * j, (char*)p ws * (j 1), ws);//交换//参数先转为char*类型再通过变量j和宽度ws就可以找到正确的指针p}}}
}
void dayin2(struct sl s[], int zs) {for (int i 0; i zs; i)printf(%s %d\n, s[i].r, s[i].b);//打印结构体中的数据printf(\n);
}
int main() {struct sl s[] {{zhangsan,18},{lisi,12},{wangwu,87}};int zs sizeof(s) / sizeof(s[0]);//求数组元素个数dayin2(s, zs);//打印原来的数组maopao(s, zs, sizeof(s[0]), cmp);//sizeof(arr[0])元素宽度dayin2(s, zs);printf(\n);return 0;
}运行结果 当然冒泡模拟的qsort还可以进行其他数据类型的排序
以上就是我的分享了如果有什么错误欢迎在评论区留言。 最后谢谢大家的观看