【C语言】模拟实现库函数qsort

news2025/3/11 6:28:56

qsort的头文件是stdlib.h

他的四个参数分别是要进行排序的数组base的首地址,base数组的元素个数,每个元素的大小,以及一个函数指针,这个函数指针指向了一个函数,这个函数的参数是两个void*类型的指针,返回类型是int,要求这个函数能够比较参数(这个函数的参数是两个指针)指向的两个元素的大小,规定如果elem1指向的元素比elem2指向的元素大,那这个函数就返回一个大于零的数,反之就返回一个小于零的数,如果elem1和elem2指向的元素一样大,就返回0。

void*类型的指针可以接收任何类型的地址,但是不能直接解引用,由于我们不知道未来要比较的两个函数是什么类型的,那就只能写成void*类型,就可以接收任何类型了,在解引用之前强制类型转换即可。

qsort默认是以升序排列的(如果要降序排列,只需要比较大小的函数返回值上用相反的逻辑即可,比如elem1指向的元素如果比elem2大,就返回一个小于零的数),并且可以排列任何类型的数组。来看一个例子

下面我们将使用回调函数模拟实现qsort,由于目前没有学习快速排序,因此使用冒泡排序代替。

模拟实现,我们就把参数设置成和库函数qsort一样,最后一个函数指针指向的是一个能比较两个元素大小的函数,需要使用者自己编写。

我们排序使用的是冒泡排序的思想,就是比较相邻的两个元素,如果前面比后面大,就交换,那现在的问题是当时冒泡排序是针对整形数组的,比较就是直接base[j]和base[j+1]进行比较即可,但是现在我们想要这个my_sort类型能够对任意类型的数据进行排序,就不能简单的写成base[j]和base[j+1],因为我们连base的类型都不知道,当然也不知道+1会跳过几个字节,也就不知道+1是不是拿到了和base[j]相邻的元素。那么我们干脆一个字节一个字节的操作,因为不管什么类型,大小至少也是一个字节,那如何操作一个字节?很简单,使用char类型的指针即可。因此不管base代表什么类型的数组,我们都先把base强制类型转换成char*类型,那么base[j]其实就是(char*)base+j*size,与他相邻的元素就是(char*)base+(j+1)*size。

这样我们就拿到了要比较的两个元素,但是这两个元素如何比较?直接使用大于号显然是不合理的,这时候就用到了我们的第四个参数,cmp函数,我们需要自己写一个能够比较两个元素大小的函数,并且规定如果前者大,就返回一个大于0的数,反之就返回一个小于0的数,如果二者相等,就返回0。

通过判断cmp函数的返回值,我们就知道了需不需要交换这两个元素。那问题又来了,如何交换?直接创建临时变量吗?那临时变量是什么类型的呢?但是要交换的数据是什么类型,他们最小也有一个字节,那么我们直接一个字节一个字节的交换就行,什么时候才算交换结束呢?当然是交换完size个字节后,就结束了。如图是swap函数的交换

这样我们的my_sort函数就可以正常使用了,比如我们要排序的是一个整形数组,我们就要去写一个能够比较两个整形数据的函数,比如这样写

如果我们要比较两个结构体类型的数据呢?

假如结构体类型是这样的

如何比较两个struct stu类型变量的大小?

由于上面的结构体类型含有两个成员变量,那么要比较struct sut类型变量的大小,就可以按照name的大小来进行比较,也可以按照age的大小进行比较,当然如果按照name的大小来进行比较,就不能直接相减了,因为字符串的比较是用库函数strcmp,这个库函数的返回值逻辑与我们的cmp函数一致,也是前者大就返回大于零的数,后者大就返回小于零的数,一样大就返回0,因此我们如果按照name的大小来比较的话,直接返回strcmp的值就可以,如图

注:由于空指针是无法进行解引用操作的,因此我们在写cmp函数的时候都需要进行强制类型转换,要比较的是什么类型的,就强制类型转换成对应的指针。

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

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

相关文章

《Linux 简易速速上手小册》第9章: 备份与恢复策略(2024 最新版)

文章目录 9.1 理解备份的重要性9.1.1 重点基础知识9.1.2 重点案例:数据中心遭受火灾9.1.3 拓展案例:个人电脑硬盘故障9.1.4 企业级数据库被恶意软件加密 9.2 实施备份策略9.2.1 重点基础知识9.2.2 重点案例:为中小企业实施备份策略9.2.3 拓展…

算法学习——LeetCode力扣二叉树篇5

算法学习——LeetCode力扣二叉树篇5 513. 找树左下角的值 513. 找树左下角的值 - 力扣(LeetCode) 描述 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 示例 1: 输入: r…

mac无法往硬盘里存东西 Mac硬盘读不出来怎么办 Mac硬盘格式 硬盘检测工具

mac有时候会出现一些问题,比如无法往硬盘里存东西,或者无法往硬盘上拷贝文件。这些问题会给用户带来很大的困扰,影响正常的工作和学习。那么,mac无法往硬盘里存东西,mac无法往硬盘上拷贝怎么办呢?软妹子将为…

【C++】类的隐式类型转换

文章目录 前言一、隐式类型转换二、explicit关键字总结 前言 一、隐式类型转换 C 类的隐式类型转换是指当一个类定义了适当的构造函数或转换函数时,可以在需要时自动进行类型转换,而无需显式调用转换函数或构造函数。这使得代码更具灵活性和简洁性。下面…

基于RBF神经网络的自适应控制器simulink建模与仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1自适应控制器 4.2 RBF神经网络模型 5.完整程序 1.程序功能描述 在simulink中,使用S函数编写基于RBF神经网络的自适应控制器,然后实现基于RBF神经网络的自适应控制…

Linux下的自动化任务与计划任务:让你的系统更智能

在日常的Linux系统管理中,你是否经常需要定时执行某些任务,或者希望在系统启动时自动运行某些脚本?如果是的话,那么自动化任务和计划任务将是你的得力助手。它们可以帮助你提高系统效率、减少人工干预,并确保任务能够按…

OCP使用CLI创建和构建应用

文章目录 环境登录创建project赋予查看权限部署第一个image创建route检查pod扩展应用 部署一个Python应用连接数据库创建secret加载数据并显示国家公园地图 清理参考 环境 RHEL 9.3Red Hat OpenShift Local 2.32 登录 通过 crc console --credentials 可以查看登录信息&…

MyBatis篇----第二篇

系列文章目录 文章目录 系列文章目录前言一、MyBatis 框架适用场合二、MyBatis 与 Hibernate 有哪些不同?三、#{}和${}的区别是什么?四、当实体类中的属性名和表中的字段名不一样 ,怎么办?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一…

WordPress修改所有用户名并发送邮件通知的插件Easy Username Updater

前面跟大家介绍了『如何修改WordPress后台管理员用户名?推荐2种简单方法』一文,但是对于有很多用户的站长来说,操作有点复杂,而且无法发邮件通知对方,所以今天boke112百科向大家推荐一款可以直接在WordPress后台修改所…

数模.微分方程

或者可以建立一个是实时脚本,也可以转化成上图公式 solver只是一个代名词,代表的是后面七种函数的名字 百分之九十用ode45函数 注意df1是在另外一个文件里面 计算导弹追击问题没有记录,去文件找代码

拼写检查应用程序:基于词典编辑的解释

一、说明 拼写检查器项目涉及创建一个可以自动检测并纠正给定文本中的拼写错误的程序。此类项目在各种应用程序中非常有用,例如文字处理器、电子邮件客户端和网络浏览器,可确保用户生成的文本没有拼写错误。 您可以找到我创建的拼写检查器应用程序&#…

数据结构哈希表

这里个大家用数组来模拟哈希表 法一&#xff1a;拉链法 法二&#xff1a;开放寻址法 /** Project: 11_哈希表* File Created:Sunday, January 17th 2021, 2:11:23 pm* Author: Bug-Free* Problem:AcWing 840. 模拟散列表 拉链法*/ #include <cstring> #include <iostr…

分享84个jQuery特效,总有一款适合您

分享84个jQuery特效&#xff0c;总有一款适合您 84个jQuery特效下载链接&#xff1a;https://pan.baidu.com/s/1P9fmHWRdaCRMXr3H9sNA1A?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理…

鸿蒙系统进一步学习(一):学习资料总结,少走弯路

随着鸿蒙Next的计划越来越近&#xff0c;笔者之前的鸿蒙系统扫盲系列中&#xff0c;有很多朋友给我留言&#xff0c;不同的角度的问了一些问题&#xff0c;我明显感觉到一点&#xff0c;那就是许多人参与鸿蒙开发&#xff0c;但是又不知道从哪里下手&#xff0c;因为资料太多&a…

<网络安全>《28 常用安全标准》

《常用安全标准》 1 个人信息安全 o《信息安全技术 个人信息安全规范》&#xff08;GB/T35273-2017) o《信息安全技术 个人信息去标识化指南》&#xff08;GB/T37964-2019) 2 工业控制安全 o《信息安全技术 工业控制系统安全检查指南》&#xff08;GB/T 37980-2019) o《信息…

STM32 SYSTick高精度延时功能代码实现

文章目录 前言一、SYSTick定时器介绍二、SYSTick定时器和其他定时器的区别三、SYSTick定时器框图讲解四、HAL库中SYSTick配置代码讲解五、SYSTick实现高精度延时总结 前言 本篇文章将给大家讲解一下SYSTICK滴答定时器&#xff0c;以及讲解使用滴答定时器来实现高精度延时功能的…

【51单片机】DS18B20(江科大)

一、DS18B20温度传感器 1.DS18B20介绍 DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点 测温范围 :- 55℃到125℃ 通信接口:1-Wire(单总线) 其它特征:可形成…

复旦TravelPlanner让大语言模型挑战旅程规划

引言&#xff1a;探索语言智能的新疆界——旅行规划 在人工智能的发展历程中&#xff0c;规划一直是核心追求之一。然而&#xff0c;由于缺乏人类水平规划所需的多种认知基础&#xff0c;早期的AI代理主要集中在受限的环境中。随着大语言模型&#xff08;LLMs&#xff09;的出…

[ai笔记5] 个人AI资讯助手实战

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵重学ai以及成长思考的第5篇分享&#xff0c;也是把ai场景化应用的第一篇实操内容&#xff01; 既然要充分学习和了解ai&#xff0c;自然少不了要时常看看ai相关资讯&#xff0c;所以今天特地用字节的“扣子”做了一个ai的资讯…

ChatGPT高效提问—prompt实践

ChatGPT高效提问—prompt实践 ​ 探索prompt在实际生活中的各种应用&#xff0c;旨在帮助理解和掌握如何将之前学到的prompt基础和技巧应用到具体实践中&#xff0c;从而在各个领域实现人工智能的价值。 ​ 通过生动的案例&#xff0c;发现并挖掘ChatGPT和prompt的无穷潜力。…