C语言:深入理解指针(5)

news2025/7/13 23:48:05

目录

一、回调函数

二、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;
   else
      return 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);
         }
   }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2377171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IEEE出版|连续多年稳定检索|第三届信号处理与智能计算国际学术会议(SPIC2025)

【重要信息】 会议官网&#xff1a; www.ic-spic.com 会议日期&#xff1a;2025年11月28-30日 会议地点&#xff1a;中国 广州 截稿日期&#xff1a;2025年11月10日 接受或拒绝通知日期&#xff1a;提交后7个工作日 【征稿主题】 人工智能和机器学习 计算机系统和架构 …

“强强联手,智启未来”凯创未来与绿算技术共筑高端智能家居及智能照明领域新生态

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

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 从理论到实战案例】

一定要拼尽全力&#xff0c;才能看起来毫不费劲 —— 25.5.15 一、提示词工程 1.提示词工程介绍 Ⅰ、什么是提示词 所谓的提示词其实就是一个提供给模型的文本片段&#xff0c;用于指导模型生成特定的输出或回答。提示词的目的是为模型提供一个任务的上下文&#xff0c;以便模…

Qt中的RCC

Qt资源系统(Qt resource system)是一种独立于平台的机制&#xff0c;用于在应用程序中传输资源文件。如果你的应用程序始终需要一组特定的文件(例如图标、翻译文件和图片)&#xff0c;并且你不想使用特定于系统的方式来打包和定位这些资源&#xff0c;则可以使用Qt资源系统。 最…

Delphi 12.3调用Chrome/edge内核实现DEMO源码

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

GitDiagram - GitHub 仓库可视化工具

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

【Linux】基于虚拟机实现网络的管理

通过学习我们需要掌握&#xff1a;IP 的配置、子网掩码、网关、DNS 服务器】 一、配置虚拟机的IP地址 1. 查看虚拟机 IP 地址&#xff08;可以看到三个地址&#xff09; ip a&#xff08;即ip address show&#xff09; 其中可以看到&#xff1a; Linux系统识别的以太网接口…

QT 使用QPdfWriter和QPainter绘制PDF文件

QT如何生产pdf文件&#xff0c;网上有许多文章介绍&#xff0c;我也是看了网上的文章&#xff0c;看他们的代码&#xff0c;自己琢磨琢磨&#xff0c;才有了本编博客&#xff1b; 其他什么就不详细说了&#xff0c;本篇博客介绍的QPdfWriter和QPainter绘制PDF文件&#xff1b;…

linux - 权限的概念

目录 用户权限 超级用户与普通用户的区别 超级用户&#xff08;root&#xff09;&#xff1a; 普通用户&#xff1a; 切换用户身份 使用sudo执行高权限命令 用户管理 用户组管理 文件权限 文件访问者类别 基本权限 权限表示方法 权限修改 chmod chown chgrp u…

【Vue】CSS3实现关键帧动画

关键帧动画 两个重点keyframesanimation子属性 实现案例效果展示&#xff1a; 两个重点 keyframes 和 animation 作用&#xff1a;通过定义关键帧&#xff08;keyframes&#xff09;和动画(animation)规则&#xff0c;实现复杂的关键帧动画。 keyframes 定义动画的关键帧序列…

AD 多层线路及装配图PDF的输出

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

MultiTTS 1.7.6 | 最强离线语音引擎,提供多音色无障碍朗读功能,附带语音包

MultiTTS是一款免费且支持离线使用的文本转语音&#xff08;TTS&#xff09;工具&#xff0c;旨在为用户提供丰富的语音包选项&#xff0c;实现多音色无障碍朗读功能。这款应用程序特别适合用于阅读软件中的离线听书体验&#xff0c;提供了多样化的语音选择&#xff0c;使得听书…

基于自校准分数的扩散模型在并行磁共振成像中联合进行线圈灵敏度校正和运动校正|文献速递-深度学习医疗AI最新文献

Title 题目 Joint coil sensitivity and motion correction in parallel MRI with aself-calibrating score-based diffusion model 基于自校准分数的扩散模型在并行磁共振成像中联合进行线圈灵敏度校正和运动校正 01 文献速递介绍 磁共振成像&#xff08;MRI&#xff09;…

OCR发票识别API实现

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

实战案例:采集 51job 企业招聘信息

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

从AlphaGo到ChatGPT:AI技术如何一步步改变世界?

从AlphaGo到ChatGPT&#xff1a;AI技术如何一步步改变世界&#xff1f; 这里给大家分享一个人工智能学习网站。点击跳转到网站。 https://www.captainbed.cn/ccc 前言 在科技发展的历史长河中&#xff0c;人工智能&#xff08;AI&#xff09;技术无疑是最为璀璨的明珠之一。从…

AI 编程革命:腾讯云 CodeBuddy 如何重塑开发效率?

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

星海智算云平台部署GPT-SoVITS模型教程

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

15:00开始面试,15:06就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到4月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…