C语言:深入理解指针(5)
目录
一、回调函数
二、qsort 使用举例
三、模拟qsort
一、回调函数
回调函数就是一个通过函数指针调用的函数。
举个例子:
int Add(int x, int y)
{return x+y;
}void test(int (*pf)(int, int))
{int r = pf(10 ,20);printf("%d\n" ,r);
}int main()
{test(Add);return 0;
}
简单点说,就是把函数的地址作为一个参数传递给另外一个函数,在其中被调用,那么被调用的函数就称为回调函数
二、qsort 使用举例
qsort 是C语言中提供的一个排序函数,是基于快速排序思想的。
它的原型如下:
void qsort(void* base, size_t num, size_t size, int(*compar)(const void* ,const void*));
void* base //指针,指向被排序数组的第一个元素
size_t num //元素个数
size_t size //元素的大小(单位:字节)
int (*compar)(const void* ,const void*) //函数指针,指向的函数是用来比较被排序数组中的两个元素,根据自己需要,自己编写
下面举个例子:
int compar(const void* p1, const void* p2)
{if( *(int*)p1 > *(int*)p2 )return 1;else if( *(int*)p1 < *(int*)p2)return -1;elsereturn 0;
}
这个自行编写的函数要满足一下要求:
(1)返回类型为整型
(2)在默认升序的情况下,当 p1 > p2时,返回1, p1 == p2 时返回 0 ,p1 < p2 时返回 -1。
(3)如果你想降序,把(2)中的 条件互换就行
(4)具体的比较标准由你自己来定,你可以比较整形,浮点型,字符型或者其他,不过要记得强制类型转换
三、用冒泡排序模拟 qsort 函数
首先,要模拟,我们需要根据 qsort 函数的原型模拟:
void my_bubble( void* base, size_t num ,size_t size, int (*compare)(const void* ,const void*);
然后我们在把原本普通的冒泡函数写出来:
void my_bubble( void* base, size_t num ,size_t size, int (*compare)(const void* ,const void*)
{for(int i = 0 ;i <sz-1;i++){for(int j = 0 ;j <sz-1-i ;j++){if(arr[j] > arr[j+1])//判断条件我们需要修改{//交换过程我们也要修改int mid = arr[j];arr[j] = arr[j+1];arr[j+1] = mid;}}
}
为什么要用void*呢?因为我们不知道要排序的数据类型
为什么要专门写一个比较函数呢?因为我们不提前知道比较规则
那如何比较两个元素呢?我们连数据类型都不知道
如图所示,我们知道起始地址,但不知道元素类型,也就不知道一个元素究竟占多少字节,整型一个元素占4个字节,短整型占两个字节,我们该如何准确地找到下一个元素的地址呢?
如图,别忘了我们还有每个元素的大小,那么第 j 个元素的地址就是 arr+j*size ,j 第 +1 个 元素的地址就是 arr + (j +1)*size 。
但是,void*作为无类型指针,是不可以被计算和解引用的,那我们就要对其强制类型转化为 char* 类型。
为什么是 char* 类型呢?因为char的大小为 1 个字节,是最小的单位了,你总不能拿 int 去吧,你用了int ,那char 、short 怎么办呢
所以那个条件应该为:
if(compar((char*)p1 ,(char*)p2) > 0)
那如果满足这个条件了,按照原先冒泡函数思想,我们就应该互换位置了,那怎么互换呢?
互换一般要创建第三个变量,但是,我们不知道元素类型,就不知道第三者变量的类型,怎么办呢?
我们每个字节每个字节互换:
如此往复循环,直到两个元素调换完成,那我们应该循环几次呢?答案是 size 次,因为每个元素就是 size 个字节,每次调换一个字节,需要调换 size 次
void Swap(char* su1, char*su2 ,size_t size)
{for(int i = 0; i<sz ;i++){char mid = *su1;*su1 = *su2;*su2 = mid;su1++;su2++;}
}
好了,我们的用冒泡排序模拟qsort就可以出来了:
void Swap(char* su1, char*su2 ,size_t size)
{for(int i = 0; i<sz ;i++){char mid = *su1;*su1 = *su2;*su2 = mid;su1++;su2++;}
}void my_bubble( void* base, size_t num ,size_t size, int (*compare)(const void* ,const void*)
{for(int i = 0 ;i <sz-1;i++){for(int j = 0 ;j <sz-1-i ;j++){if(compare((char*)p1+j*size , (char*)p2+(j+1)*size) >0){swap((char*)p1+j*size , (char*)p2+(j+1)*size) ,size);}}
}
相关文章:

C语言:深入理解指针(5)
目录 一、回调函数 二、qsort 使用举例 三、模拟qsort 一、回调函数 回调函数就是一个通过函数指针调用的函数。 举个例子: int Add(int x, int y) {return xy; }void test(int (*pf)(int, int)) {int r pf(10 ,20);printf("%d\n" ,r); }int main()…...
前端如何获取电脑唯一编码
在前端开发中,出于安全和隐私的考虑,浏览器不允许直接获取硬件的唯一标识(如 MAC 地址、CPU 序列号等)。但可以通过以下方法生成设备指纹(Device Fingerprint),近似实现设备唯一标识:…...

IEEE出版|连续多年稳定检索|第三届信号处理与智能计算国际学术会议(SPIC2025)
【重要信息】 会议官网: www.ic-spic.com 会议日期:2025年11月28-30日 会议地点:中国 广州 截稿日期:2025年11月10日 接受或拒绝通知日期:提交后7个工作日 【征稿主题】 人工智能和机器学习 计算机系统和架构 …...

“强强联手,智启未来”凯创未来与绿算技术共筑高端智能家居及智能照明领域新生态
近日,北京凯创未来科技有限公司总经理赵健凯先生莅临广东省绿算技术有限公司北京运营中心,双方正式签订战略合作协议,标志着绿算技术在高端智能家居及智能照明领域的技术实力与产业布局获得智能家居行业认可,同时也为凯创未来在高…...

MQ消息队列的深入研究
目录 1、Apache Kafka 1.1、 kafka架构设 1.2、最大特点 1.3、功能介绍 1.4、Broker数据共享 1.5、数据一致性 2、RabbitMQ 2.1、架构图 2.2、最大特点 2.3、工作原理 2.4、功能介绍 3、RocketMQ 3.1、 架构设计 3.2、工作原理 3.3、最大特点 3.4、功能介绍 3…...

【NLP 74、最强提示词工程 Prompt Engineering 从理论到实战案例】
一定要拼尽全力,才能看起来毫不费劲 —— 25.5.15 一、提示词工程 1.提示词工程介绍 Ⅰ、什么是提示词 所谓的提示词其实就是一个提供给模型的文本片段,用于指导模型生成特定的输出或回答。提示词的目的是为模型提供一个任务的上下文,以便模…...
安卓开饭-ScrollView内嵌套了多个RecyclerView,只想与其中一个RecyclerView有联动
在 Android 开发中,将 RecyclerView 嵌套在 ScrollView 内通常会导致性能问题和滚动冲突,应尽量避免这种设计。以下是原因和替代方案: 为什么不推荐 RecyclerView ScrollView? 性能损耗 RecyclerView 本身已自带高效回收复…...
Linux 系统中的文件系统层次结构和重要目录的用途。
Linux系统目录结构采用分层布局方式,通过根目录"/"组织管理各类文件。以下为核心目录说明: 一、主要目录结构 1. / : 根目录,所有文件和目录的起点 2. /bin : 存储基础用户命令(ls/cp/mv等) 3. /boot : 存放系统引导程序和…...
从攻击者角度来看Go1.24的路径遍历攻击防御
目录 一、具体攻击示例 程序 攻击步骤: 二、为什么攻击者能成功? 分析 类比理解 总结 三、TOCTOU 竞态条件漏洞 1、背景:符号链接遍历攻击 2. TOCTOU 竞态条件漏洞 3. 另一种变体:目录移动攻击 4. 问题的核心 四、防…...
使用 SiamMask 实现单目标逐帧跟踪与掩码中心提取
使用 SiamMask 实现单目标逐帧跟踪与掩码中心提取 使用 SiamMask 实现逐帧掩码中心提取与目标跟踪1. 功能概述2. 输入要求3. 使用说明4. 可选扩展5. 常见问题排查6. 脚本代码(siam\_one\_frame.py)使用 SiamMask 实现逐帧掩码中心提取与目标跟踪 本文介绍基于 SiamMask 的逐…...

Qt中的RCC
Qt资源系统(Qt resource system)是一种独立于平台的机制,用于在应用程序中传输资源文件。如果你的应用程序始终需要一组特定的文件(例如图标、翻译文件和图片),并且你不想使用特定于系统的方式来打包和定位这些资源,则可以使用Qt资源系统。 最…...
【实战解决方案】Spring Boot+Redisson构建高并发Excel导出服务,彻底解决系统阻塞难题
【实战解决方案】Spring BootRedisson构建高并发Excel导出服务,彻底解决系统阻塞难题 一、问题背景:痛苦的系统卡顿经历 作为电商后台开发者,我们经常遇到这样的场景:运营人员在后台点击"导出订单数据"后,…...

Delphi 12.3调用Chrome/edge内核实现DEMO源码
DELPHI使用调用Chrome/Edge内核浏览器,虽然旧的WebBrowser也还可以用,但大势所趋,新版的已经不需要使用第三方的组件了,算是全内置的开发了,不废话 Unit1 源码 Form 源码 unit Unit1;interfaceusesWinapi.Windows, W…...

GitDiagram - GitHub 仓库可视化工具
GitDiagram - GitHub 仓库可视化工具 项目链接:https://github.com/ahmedkhaleel2004/gitdiagram 将任何 GitHub 仓库转换为交互式架构图,只需替换 URL 中的 hub 为 diagram。 ✨ 核心功能 即时可视化:将代码库结构转换为系统设计/架构图…...

【Linux】基于虚拟机实现网络的管理
通过学习我们需要掌握:IP 的配置、子网掩码、网关、DNS 服务器】 一、配置虚拟机的IP地址 1. 查看虚拟机 IP 地址(可以看到三个地址) ip a(即ip address show) 其中可以看到: Linux系统识别的以太网接口…...

QT 使用QPdfWriter和QPainter绘制PDF文件
QT如何生产pdf文件,网上有许多文章介绍,我也是看了网上的文章,看他们的代码,自己琢磨琢磨,才有了本编博客; 其他什么就不详细说了,本篇博客介绍的QPdfWriter和QPainter绘制PDF文件;…...
英迈国际Ingram Micro EDI需求分析
Ingram Micro(英迈国际)成立于1979年,是全球领先的技术和供应链服务提供商,总部位于美国加州尔湾。公司致力于连接全球的技术制造商与渠道合作伙伴,业务涵盖IT分销、云服务、物流和供应链优化等多个领域。Ingram Micro…...

linux - 权限的概念
目录 用户权限 超级用户与普通用户的区别 超级用户(root): 普通用户: 切换用户身份 使用sudo执行高权限命令 用户管理 用户组管理 文件权限 文件访问者类别 基本权限 权限表示方法 权限修改 chmod chown chgrp u…...
函数的定义与调用 -《Go语言实战指南》
函数是 Go 编程的基本单元。Go 支持普通函数、匿名函数、高阶函数(函数作为参数或返回值)以及多返回值机制。 一、函数的定义格式 func 函数名(参数列表) 返回值列表 {// 函数体 } 示例: func add(a int, b int) int {return a b } 说明&…...
理解 Token 索引 vs 字符位置
以下是对“理解 Token 索引与字符位置的区别”的内容整理,条理清晰,结构完整,保持技术细节,方便阅读,无多余解释: 🔍 理解 Token 索引 vs 字符位置 文本分块方法中返回的索引是 token 索引&…...

【Vue】CSS3实现关键帧动画
关键帧动画 两个重点keyframesanimation子属性 实现案例效果展示: 两个重点 keyframes 和 animation 作用:通过定义关键帧(keyframes)和动画(animation)规则,实现复杂的关键帧动画。 keyframes 定义动画的关键帧序列…...

AD 多层线路及装配图PDF的输出
装配图的输出: 1.点开‘智能PDF’ 2. 设置显示顶层: 设置显示底层: 多层线路的输出 同样使用‘智能PDF’...

MultiTTS 1.7.6 | 最强离线语音引擎,提供多音色无障碍朗读功能,附带语音包
MultiTTS是一款免费且支持离线使用的文本转语音(TTS)工具,旨在为用户提供丰富的语音包选项,实现多音色无障碍朗读功能。这款应用程序特别适合用于阅读软件中的离线听书体验,提供了多样化的语音选择,使得听书…...

基于自校准分数的扩散模型在并行磁共振成像中联合进行线圈灵敏度校正和运动校正|文献速递-深度学习医疗AI最新文献
Title 题目 Joint coil sensitivity and motion correction in parallel MRI with aself-calibrating score-based diffusion model 基于自校准分数的扩散模型在并行磁共振成像中联合进行线圈灵敏度校正和运动校正 01 文献速递介绍 磁共振成像(MRI)…...

OCR发票识别API实现
OCR发票识别API实现 1. 阿里云OCR发票识别2. Tesseract OCR3. 利用java调用大模型进行识别4. 飞桨PaddleOCR 1. 阿里云OCR发票识别 阿里云OCR发票识别 示例: 接口:https://dgfp.market.alicloudapi.com/ocrservice/invoice 参数:{"img&…...

实战案例:采集 51job 企业招聘信息
本文将带你从零开始,借助 Feapder 快速搭建一个企业级招聘信息数据管道。在“基础概念”部分,我们先了解什么是数据管道和 Feapder;“生动比喻”用日常场景帮助你快速理解爬虫组件;“技术场景”介绍本项目中如何使用代理等采集策略…...

从AlphaGo到ChatGPT:AI技术如何一步步改变世界?
从AlphaGo到ChatGPT:AI技术如何一步步改变世界? 这里给大家分享一个人工智能学习网站。点击跳转到网站。 https://www.captainbed.cn/ccc 前言 在科技发展的历史长河中,人工智能(AI)技术无疑是最为璀璨的明珠之一。从…...
推荐6大wordpress模板资源网站
1. 模板之家 模板之家是一个提供丰富网站模板资源的平台。它涵盖了多种类型的模板,包括企业官网、个人博客、电商网站等,能够满足不同用户对于网站搭建的需求。其模板设计精美,功能多样,且注重用户体验,方便用户快速搭…...

AI 编程革命:腾讯云 CodeBuddy 如何重塑开发效率?
引言 在传统开发流程中,开发者常需依赖 SDK 文档或反复调试来获取云资源信息。而随着 AI 技术爆发式发展,腾讯云推出的 CodeBuddy 正以对话式编程颠覆这一模式 —— 只需自然语言描述需求,即可直接生成可执行代码。作为腾讯混元大模型与 Dee…...

星海智算云平台部署GPT-SoVITS模型教程
背景 随着 GPT-SoVITS 在 AI 语音合成领域的广泛应用,越来越多的个人和团队开始关注这项前沿技术。你是否也在思考,如何快速、高效地部署并体验这款强大的声音克隆模型?遗憾的是,许多本地部署方案不仅配置复杂,而且对…...