指针修仙之实现qsort

文章目录

  • 回调函数
    • 什么是回调函数
    • 回调函数的作用
  • 库函数qsort
    • 使用qsort函数排序整形
    • 使用qsort函数排序结构体
  • qsort函数模拟实现
    • 说明
    • 源码`and`说明


回调函数

什么是回调函数

回调函数就是⼀个通过函数指针调⽤的函数。
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。
简单说,回调函数就是用函数指针也就是函数的地址来调用函数。

回调函数的作用

回调函数可以减少函数的冗余,并且可以使函数的功能更加丰富,实现泛型编程,我们之间从下面qsort的模拟实现中体会

库函数qsort

我们看一下qsort的官方描述
在这里插入图片描述
分析以下函数的参数,依次是:

  1. 数组首元素地址
  2. 数组元素个数
  3. 数组元素大小
  4. 自定义比较函数的地址

使用qsort函数排序整形

int cmp_int(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}
int main()
{int arr[] = { 2,4,3,5,9,8,6,7,1,0 };qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), cmp_int);return 0;
}

注意 自定义比较函数的参数类型是void*,要先将地址强制类型转换成int*再解引用

使用qsort函数排序结构体

#include<string.h>
int cmp_stu_by_age(const void* p1, const void* p2)
{return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
struct Stu
{char name[10];int age;
};
int main()
{struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}

注意 比较字符串时要用库函数strcmp

qsort函数模拟实现

说明

回顾我这个编程小白的排序技能库,似乎只会一种冒泡排序,所以下面模拟实现qsort是在冒泡排序的基础上改进完成的

源码and说明

主体部分

void bubble_sort_plus(void* base, size_t num, size_t size, void* cmp(const void*, const void*))
{for (int i = 0; i < num-1; i++){for (int j = 0; j < num - i - 1; j++){if (cmp((char*)base + j*size, (char*)base + (j+1)*size) > 0){Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}

注意

  • 函数参数和库函数中的qsort类型相同
  • 内层循环的判断条件
    • 通过地址来调用用户自定义的比较函数,自定义的比较函数的参数,强制转换成char* 找到元素第 一个字节的地址,然后再加上每一个元素的宽度,即可访问数组中的元素
    • 使用函数地址来调用函数,cmp函数是一个回调函数,使用户自定义函数类型,丰富了函数的功能
  • 实现交换功能
    • 由于不知道用户传递来的函数数据类型,因此只能先强制转换为char*类型的数据,通过一个一个的字节来访问元素

Swap函数

void Swap(char* p1, char* p2, size_t size)
{for (int i = 0; i < size; i++){char tmp = *p1;*p1 = *p2;*p2 = tmp;p1++;p2++;}
}

注意

  • 函数参数直接用char*类型来接收
  • 设计参数size,可以控制交换字节的个数
  • 交换的原理是一个字节一个字节的交换

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

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

相关文章

深度学习02-pytorch-01-张量的创建

深度学习 pytorch 框架 是目前最热门的。 深度学习 pytorch 框架相当于 机器学习阶段的 numpy sklearn 它将数据封装成张量(Tensor)来进行处理&#xff0c;其实就是数组。也就是numpy 里面的 ndarray . pip install torch1.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simp…

蓝桥杯【物联网】零基础到国奖之路:七. 串口

蓝桥杯【物联网】零基础到国奖之路:七. 串口 第一节 串口通信理论第二节 软件通信协议第三节 DMA理论第四节 CubeMX的配置第五节 代码模版 第一节 串口通信理论 通用异步收发传输器&#xff08;UART&#xff09;是一种串行异步收发协议&#xff0c;应用十分广泛。UART将数据二…

HashMap扩容时机是插入前还是插入后?

结论 不管是HashMap还是ConcurrentHashMap都是插入后。 过程为&#xff1a; 先计算哈希值。对应的哈希槽插入数据&#xff0c;决定是红黑树还是链表插入完毕才计算是否需要扩容&#xff0c;假如需要则扩容 源码 源码如下&#xff1a; 其中addCount方法里面写入扩容。

Dash稳定版更新

大家好&#xff0c;今天要和大家聊聊一个开发Python网页应用的超级神器——Dash 2.18.1稳定版本正式发布啦&#xff01;此次更新&#xff0c;针对2.18.0版本的问题进行了修复和优化&#xff0c;为我们带来了更为稳定、强大的开发体验。 Dash是什么&#xff1f; Dash是一款基于P…

深度学习03-神经网络02-激活函数

可以使用这个进行跳转链接​​​​​​​http://playground.tensorflow.org/#activationrelu&batchSize11&datasetspiralDatasetreg-gauss&learningRate0.01ularizationRate0.1&noise0&networkShape7,5,4,3,2&seed0.54477&showTestDatafalse&d…

Excel VLOOKUP函数怎么用?vlookup函数的使用方法及案例

大家好&#xff0c;这里是效率办公指南&#xff01; &#x1f50e; 在Excel的世界里&#xff0c;VLOOKUP函数无疑是查询和数据分析中的明星。无论是从庞大的数据表中提取特定信息&#xff0c;还是进行数据的快速匹配&#xff0c;VLOOKUP都能大显身手。今天&#xff0c;我们将深…

第15章 程序的动态加载和执行

第15章 程序的动态加载和执行 该章节讲解了MBR加载内核&#xff0c;然后内核加载用户程序这样一套流程&#xff0c;模拟操作系统的工作原理。 本章代码清单 本章的代码实现的功能位&#xff1a;主引导扇区加载内核&#xff0c;内核加载用户程序&#xff0c;用户程序通过调用…

速通LLaMA3:《The Llama 3 Herd of Models》全文解读

文章目录 概览论文开篇IntroductionGeneral OverviewPre-TrainingPre-Training DataModel ArchitectureInfrastructure, Scaling, and EfficiencyTraining Recipe Post-TrainingResultsVision ExperimentsSpeech Experiments⭐Related WorkConclusionLlama 3 模型中的数学原理1…

【力扣每日一题——2374. 边积分最高的节点】python

2374. 边积分最高的节点 给你一个有向图&#xff0c;图中有 n 个节点&#xff0c;节点编号从 0 到 n - 1 &#xff0c;其中每个节点都 恰有一条 出边。 图由一个下标从 0 开始、长度为 n 的整数数组 edges 表示&#xff0c;其中 edges[i] 表示存在一条从节点 i 到节点 edges[…

mimics教程案例1-骨折三维重建

骨折三维重建 1 打开软件新建工程&#xff0c;将数据导入 FILE -> New Project ->找到自己的数据 ->Next ->Open 2 新建图层 SEFMENT -> New Mask ->选择阈值&#xff08;合适的阈值是可以将骨骼边缘覆盖住&#xff09;-> OK 3 使用Region Grow(区域增…

【全网最全】2024年华为杯研赛B题成品论文获取入口(后续会更新)

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 点击链接加入【2024华为杯研赛资料汇总】&#xff1a;https://qm.qq.com/q/hMgWngXvcQhttps://qm.qq.com/q/hMgWngXvcQ你是否在寻找数学建模比赛的突破点&a…

【无标题】HG6201M路由的超级管理密码获取

这里写自定义目录标题 1、开启telnet http://192.168.1.1/cgi-bin/telnetenable.cgi?telnetenable1&keyXXXXX 注意&#xff1a;此处的XXXXX为路由背面标签的MAC地址&#xff0c;去掉“-”&#xff0c;且大写。 成功后会显示&#xff1a;telnet开启 2、登录telnet 此处采…

GB28181协议接入SVMSPro平台

国标28181协议接入SVMSPro平台 步骤一&#xff1a;海康摄像机28181配置&#xff1b;登录海康摄像机网页进配置选项&#xff0c;左边选网络-高级设置-平台接入-类型选28181 勾选启用&#xff0c;28181协议版本选最新2016 SIP服务器ID:默认20位 34020000002000000001,也可在服务端…

SVTR文字识别

论文地址&#xff1a;https://arxiv.org/abs/2205.00159 notes&#xff1a; 论文2.5中说的N nodes&#xff0c;就是输出的类别数量&#xff0c;英文37&#xff0c;中文6625&#xff0c;英文37说的是最简单的英文文字识别任务&#xff0c;不区分大小写&#xff0c;就是26个字母…

数据库(选择题)

基本概念 数据库&#xff08;DB&#xff09;&#xff1a;长期存储在计算机内的、有组织的、可共享的数据集合。 数据库管理系统&#xff08;DBMS&#xff09;&#xff1a;它是数据库的机构&#xff0c;是一个系统软件&#xff0c;负责数据库中的数据组织、数据操纵、数据维护…

AiAutoPrediction足球网与泊松分布足球预测比赛模型介绍

AiAutoPrediction足球软件上线于2020年9月&#xff0c;是国内首家将泊松分布概率公式应用于足球比赛比分预测的软件。 AiAutoPrediction足球系列软件如下&#xff1a; AIAutoPrediction SoccerPredictor |走地大小球|走地让球|走地角球|数据分析 AiScorePredictor 泊松分布…

日志系统第一弹:日志系统介绍

日志系统第一弹&#xff1a;日志系统介绍 一、日志的重要性1.什么是日志&#xff1f;2.排查BUG3.监控系统4.监控程序性能 二、日志系统技术1.同步写日志2.异步写日志3.日志文件轮换方案1.日志分类方式2.日志轮换方案 三、项目设计1.目标2.设计1.日志消息模块2.日志格式化模块3.…

在python爬虫中xpath方式提取lxml.etree._ElementUnicodeResult转化为字符串str类型

简单提取网页中的数据时发现的 当通过xpath方式提取出需要的数据的text文本后想要转为字符串&#xff0c;但出现lxml.etree._ElementUnicodeResult的数据类型不能序列化&#xff0c;在网上查找到很多说是编码问题Unicode编码然后解码什么的&#xff1b;有些是(导入的xml库而不…

LeetCode讲解篇之1343. 大小为 K 且平均值大于等于阈值的子数组数目

文章目录 题目描述题解思路题解代码 题目描述 题解思路 题目让我们求长度为k的子数组并且该子数组的平均值大于threshold&#xff0c;对于这题&#xff0c;我们可以考虑维护一个长度为k的窗口&#xff0c;窗口不断向右滑动&#xff0c;遍历所有长度为k的子数组&#xff0c;我们…

基于Spring Boot的Java免税商品优选商城设计

第一章 绪论 1.1 课题开发的背景 从古至今&#xff0c;通过书本获取知识信息的方式完全被互联网络信息化&#xff0c;但是免税商品优选购物商城&#xff0c;对于购物商城工作来说&#xff0c;仍然是一项非常重要的工作。尤其是免税商品优选购物商城&#xff0c;传统人工记录模式…