ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

C语言——深度理解指针(5)

2026/8/20 14:19:12 拓冰建站 浏览量
C语言——深度理解指针(5) 耕耘 :C、C、嵌入式技术领域我的个人主页❄️个人专栏《C语言专栏》 《嵌入式专栏》✨**不要等待机会而要创造机会**✨博主简介:✨✨一位热爱生活的阳光大男孩.✨✨前言本文深入浅出地讲解了C语言中两个核心概念回调函数与qsort函数。回调函数作为函数指针的典型应用是实现灵活编程和事件响应的关键而qsort则是C标准库中功能强大的通用排序工具。文章将从回调函数的基本原理出发结合qsort对各种数据类型整型、字符、字符串、浮点型、结构体的排序实践通过丰富的代码示例帮助你掌握其用法与设计思想提升C语言编程能力。文章目录前言1. 回调函数是什么2. qsort 使⽤举例2.1 使⽤qsort函数排序整型数据2.2 使⽤qsort排序结构数据结语1. 回调函数是什么回调函数就是⼀个通过函数指针调⽤的函数。如果你把函数的指针地址作为参数传递给另⼀个函数当这个指针被⽤来调⽤其所指向的函数时被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的⽤于对该事件或条件进⾏响应.。下面我们用代码实现一个加法运算intadd(inta,intb)//加法运算{returnab;}voidcalc(int(*pf)(int,int))//用calc调用add函数{intret0;intx,y;scanf_s(%d %d,x,y);retpf(x,y);printf(%d\n,ret);}intmain(){calc(add);return0;}上面代码中我们没有直间使用add函数而是把add的指针给了calc函数间接的调用了add函数。这就是回调函数。2. qsort 使⽤举例2.1 使⽤qsort函数排序整型数据首先我们先来认识一下什么是qsort函数qsort 是 C 标准库中提供的快速排序函数用于对数组进行排序。它能够对任意类型的数据进行排序通过用户自定义的比较函数实现灵活的排序规则。qsort函数的头文件stdlibqsort函数需要提供四个数据voidqsort(void*base,// 数组首元素地址size_tnmemb,// 数组元素个数size_tsize,// 每个元素的大小字节int(*compar)(constvoid*,constvoid*)// 比较函数的指针);用qsort函数进行升序运算1、排序对象是int时#includestdio.h#includestdlib.h//qsort函数的头文件//qosrt函数的使⽤者得实现⼀个⽐较函数intint_cmp(constvoid*p1,constvoid*p2){return(*(int*)p1-*(int*)p2);//因为p1和p2原先定义的时候是void*所以不可以直接解引用因为数组中元素类型是int所以要先强制转化成int*后在解引用}intmain(){intarr[]{1,3,5,7,9,2,4,6,8,0};inti0;qsort(arr,sizeof(arr)/sizeof(arr[0]),sizeof(int),int_cmp);//使用方法首元素地址数组元素个数元素的大小字节比较函数的指针for(i0;isizeof(arr)/sizeof(arr[0]);i){printf(%d ,arr[i]);}printf(\n);return0;}const void* p1: 指向数组中第一个待比较元素的指针。const void* p2: 指向数组中第二个待比较元素的指针。比较函数需返回整数也就是p1指向的值-p2指向的值负数第一个参数应排在第二个参数之前。0两参数相等。正数第一个参数应排在第二个参数之后2、排序对象是char类型时#includestdio.h// 用于输入输出#includestdlib.h// 用于qsort函数// 比较函数用于比较两个字符的大小intcompare_chars(constvoid*a,constvoid*b){charchar_a*(constchar*)a;charchar_b*(constchar*)b;returnchar_a-char_b;}intmain(){chararr[]{d,a,c,b,e};intsizesizeof(arr)/sizeof(arr[0]);qsort(arr,size,sizeof(char),compare_chars);// 使用 qsort 对字符数组进行排序for(inti0;isize;i)// 打印排序后的字符数组{printf(%c ,arr[i]);}return0;}3、排序对象是字符串类型时#includestdio.h// 用于输入输出#includestdlib.h// 用于qsort函数#includestring.h// 用于strcmp函数intcompareStrings(constvoid*p1,constvoid*p2){// 将void指针转换为指向字符串指针的指针charstr1[]* (char*)p1;charstr2[]* (char*)p2;returnstrcmp(str1,str2);// 使用strcmp比较字符串}intmain(){char*strings[]{banana,apple,orange,grape,pear};// 定义一个字符串数组intnumStringssizeof(strings)/sizeof(strings[0]);qsort(strings,numStrings,sizeof(char*),compareStrings);// 使用qsort对字符串数组进行排序for(inti0;inumStrings;i){printf(%s\n,strings[i]);// 打印排序后的结果}return0;}注意字符串比较要用strcmp函数4、排序对象是浮点型类型时#includestdio.h#includestdlib.hintcompare_floats(constvoid*a,constvoid*b)// 浮点数比较函数{floatfa*(constfloat*)a;floatfb*(constfloat*)b;// 处理浮点数精度问题if(fafb){return-1;}if(fafb){return1;}return0;}intmain(){floatnumbers[]{3.14f,1.59f,2.65f,3.58f,9.79f,3.23f};intsizesizeof(numbers)/sizeof(numbers[0]);// 使用qsort排序qsort(numbers,size,sizeof(float),compare_floats);// 打印排序结果for(inti0;isize;i){printf(%.2f ,numbers[i]);}return0;}2.2 使⽤qsort排序结构数据排序对象是结构体函数#includestdio.h// 用于输入输出#includestdlib.h// 用于qsort函数#includestring.h// 用于strcmp函数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}};intsz(sizeof(s)/sizeof(s[0]));qsort(s,sz,sizeof(s[0]),cmp_stu_by_name);}intmain(){test2();//按照年龄来排序test3();//按照名字来排序return0;}补充结构体成员访问操作符 -通过指针间接访问结构体变量的成员structStu//定义一个嵌套函数{charname[20];//名字intage;//年龄};intmain(){structStus{zhangsan,20};structStu*xs;printf(%d\n,x-age);return0;}. 操作符用于直接访问结构体变量的成员structStu//定义一个嵌套函数{charname[20];//名字intage;//年龄};intmain(){structStus[]{zhangsan,20};printf(%d\n,s.age);return0;}结语“三连到位坐等回关~”完。