ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

C 语言指针从入门到避坑:把指针踩在脚底(5)

C 语言指针从入门到避坑:把指针踩在脚底(5) 目录回调函数是什么qsort使用举例使用qsort函数排序整型数据使用qsort排序结构体数据qsort的模拟实现回调函数是什么回调函数用形象话的语言描述就是B,C,D,E函数的指针地址分别作为参数传入A函数中最后再由指针回调函数的时候这时被调用的函数就是回调函数qsort使用举例qsort是一个库函数头文件是stdlib.h。它是用来对数据进行排序的基于快速排序的思想对数据进行排序可以对任意数据类型进行排序。使用qsort函数排序整型数据在使用qsort前我们要知道使用qsort时必须要传入的四个参数voidqsort(void*base,//指针指向了要排序数组的第一个元素size_tnum,//用于计算base所指数组中元素的个数size_tsize,//用于计算base所指数组中一个元素的字节数int(*compare)(const*p1,const*p))//函数指针,指向一个函数指向的函数用于比较base所指数组中任意两个数据的大小对compare所指向函数的返回值要求函数的返回值要能体现p1,p2指向数据的大小*若 p1指向的数据p2指向的数据返回值0*若 p1指向的数据p2指向的数据返回值0若p1指向的数据p2指向的数据返回值0这种方法默认的是升序排列若降序只需调换p1和p2的顺序例如 若 p2指向的数据p1指向的数据返回值0。#includestdlib.hintcom_int(constvoid*p1,constvoid*p2){return*(int*)p1-*(int*)p2;//void*不能直接解引用要强制转换为对应的类型}intmian(){intarr[5]{3,2,1,5,4};intszsizeof(arr)/sizeof(arr[0]);qsort(arr,sz,sizeof(arr[0],com_int);for(inti0;isz;i){printf(%d,arr[i]);//打印数组检验结果return0;}使用qsort排序结构体数据structStu//学⽣{charname[20];//名字intage;//年龄};//假设按照年龄来⽐较intcmp_stu_by_age(constvoid*e1,constvoid*e2){return((structStu*)e1)-age-((structStu*)e2)-age;}//strcmp - 是库函数是专⻔⽤来⽐较两个字符串的⼤⼩的//假设按照名字来⽐较intcmp_stu_by_name(constvoid*e1,constvoid*e2){returnstrcmp(((structStu*)e1)-name,((structStu*)e2)-name);}//按照年龄来排序voidtest2(){structStus[]{{zhangsan,20},{lisi,30},{wangwu,15}};intszsizeof(s)/sizeof(s[0]);qsort(s,sz,sizeof(s[0]),cmp_stu_by_age);}//按照名字来排序voidtest3(){structStus[]{{zhangsan,20},{lisi,30},{wangwu,15}};intszsizeof(s)/sizeof(s[0]);qsort(s,sz,sizeof(s[0]),cmp_stu_by_name);}intmain(){test2();test3();return0;}qsort的模拟实现这里以冒泡排序为例子来模拟实现qsort#includestdio.h// 比较函数用于比较两个整型数据的大小// 返回值 0 表示 p1 指向的数据大于 p2 指向的数据// 返回值 0 表示 p1 指向的数据小于 p2 指向的数据// 返回值 0 表示两个数据相等intcmp(constvoid*p1,constvoid*p2){// void* 不能直接解引用需要强制转换为 int* 后再解引用return*(int*)p1-*(int*)p2;}// 交换函数按字节交换两个内存区域的数据// b1指向第一个数据的起始地址// b2指向第二个数据的起始地址// width每个数据占用的字节数即单个元素的宽度voidsort(char*b1,char*b2,size_twidth){size_ti0;// 逐字节交换两个数据区域的内容for(i;iwidth;i){chartmp*b1;// 暂存 b1 当前字节*b1*b2;// 将 b2 的字节赋给 b1*b2tmp;// 将暂存的字节赋给 b2b1;// 指针后移处理下一个字节b2;}}// 模拟 qsort 的冒泡排序实现// base指向待排序数组首元素的指针void* 可接收任意类型// sz数组中元素的个数// width每个元素占用的字节数// cmp函数指针指向用户提供的比较函数voidbubble_sort(void*base,size_tsz,size_twidth,int(*cmp)(constvoid*p1,constvoid*p2)){inti0;// 外层循环控制排序的趟数共 sz-1 趟for(i0;isz-1;i){intj0;// 内层循环每趟比较相邻元素将最大值逐步冒泡到末尾for(j0;jsz-1-i;j){// 通过指针运算定位第 j 个和第 j1 个元素的起始地址// (char*)base 转为 char* 后加上 j*width 即可跳过 j 个元素if(cmp((char*)basej*width,(char*)base(j1)*width)0){// 若前一个元素大于后一个元素则交换它们sort((char*)basej*width,(char*)base(j1)*width,width);}}}}intmain(){intarr[5]{5,4,3,2,1};// 待排序的整型数组intszsizeof(arr)/sizeof(arr[0]);// 计算数组元素个数intwidthsizeof(arr[0]);// 计算单个元素占用的字节数bubble_sort(arr,sz,width,cmp);// 调用模拟的 qsort 进行排序intb0;// 遍历打印排序后的数组验证排序结果for(b;b5;b){printf(%d,arr[b]);}return0;}
返回列表