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

发布时间:2026/10/6 11:53:10

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;}结语“三连到位坐等回关~”完。
延伸阅读

更多相关文章

2026/10/1 10:01:54

汽车零售数字化转型:渠道下沉、全生命周期运营与OMO融合实战

1. 从“卖车”到“经营用户”:汽车零售的本质变迁 最近和几个在主机厂、经销商集团和新兴零售平台的朋友聊天,大家不约而同地提到一个词:焦虑。这种焦虑,不是来自销量的短期波动,而是源于一种深刻的行业共识——过去那…

2026/10/4 14:29:55

116-平台落地路线图:如果从零开始,应该先搭哪几层

适合对象:准备建设类似平台的技术负责人、架构师和工程团队。 先说结论 平台落地路线图不是一个孤立功能,而是精准测试平台里帮助团队做判断的一环。 它重点解决的是:如果从零开始,应该先搭哪几层。 用大白话讲,先把建设顺序、角色分工和长期治理讲清楚,平台才不会做成…

2026/10/6 11:49:06

无人机飞控硬件设计:传感器、电源与驱动的可靠性实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 11:49:06

DeepSeek-V3 API多模态调用实战:图像转文本与文案生成全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 11:49:06

ESP32-C3 QFN32封装设计全解析:从焊盘尺寸到EMC接地实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 11:49:06

从模电视角读懂调音台话放:输入级、增益与噪声的工程逻辑

写给音响工程师的科普文章(二)——从模电角度去了解调音台话放 把话放电路图纸摊开在面前的时候,很多做了好几年演出的音响工程师会下意识地去找那颗最大的运放型号。这个习惯我太熟悉了,因为我一开始也是这样。但实际调试经验告诉…

2026/10/6 11:49:06

手把手实现MIPS32单周期CPU:Verilog数据通路与仿真验证全解析

折腾完Verilog单周期CPU设计之后,我最大的感受是:CPU这东西看着玄乎,把它拆成一条数据通路再逐段实现,其实比想象中要清晰得多。这篇笔记是我完整走完一遍MIPS32单周期CPU设计后整理的超详细复盘,从指令集选型、数据通…

2026/10/6 11:44:06

电容好坏怎么判断?万用表三招实测:容量、漏电、ESR全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/6 4:01:51

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/5 17:38:27

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 0:03:23

MR25H40CDF+STM32F031C6工业级高可靠数据存储方案

1. 项目概述:为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储?在工厂产线的 PLC 控制柜里、在风电变流器的散热片背面、在矿井监测终端的金属外壳下,你经常能看到一块指甲盖大小的黑色芯片——它既不是 Flash,也不是…

2026/10/6 0:03:23

MRAM+STM32工业断电数据保全实战指南

1. 项目概述:为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储?在工厂产线的PLC柜里、在野外无人值守的环境监测终端里、在高速运转的包装机控制板上,你经常能看到一块指甲盖大小的黑色芯片,旁边贴着“MR25H40CDF”丝…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑