C语言-qosrt函数—秩序大师

news2024/11/15 7:05:47

1、qsort()的作用

在我们的日常生活中,排序无处不在。想象一下,当你整理书架时,会按照书籍的类别、作者或者大小进行排列,让你的阅读空间更加整洁有序。又比如,在超市的货架上,商品通常也是按照一定的规则进行排序,方便顾客快速找到所需物品。在学校里,老师可能会根据学生的成绩进行排名,以了解学生的学习情况。

而在计算机编程的世界里,同样需要对数据进行高效的排序。这时,qsort 函数就如同一位强大的秩序之师,挺身而出。qsort 函数是 C 语言标准库中的快速排序函数它能够快速而有效地对各种数据进行排序。无论是简单的整数数组,还是复杂的结构体数组,qsort 函数都能轻松应对。它以其高效的性能和灵活的用法,成为了程序员们在处理数据排序问题时的得力助手。

说了这么多,接下来我们也该来见一见这位秩序大师的庐山真面目了!

2、qsort函数的基本信息

在cplusplus(C语言函数查询网站)上,我们可以看到qsort函数的函数原型

eb4f368f71f443cba37f527e5159ca93.png

qsort函数是有4个变量的,分别是base,num,size,comper

他们的类型分别是void*;size_t;size_t;int(*)(const void*,const void*);

cplusplus上对这四个变量的解释:(下图为机翻,因此可能会有些不准确)

33016d7eece44e29a4237b64a4727c2e.png

对上面的参数解释的理解:

  • base:base中存放的是待排序数组的第一个元素的地址
  • num:num存放的是base指向的数组的元素个数
  • size:size是base指向的数组中一个元素的长度(以字节为单位)。
  • comper:函数指针—指向了一个比较函数,这个比较函数用来比较数组中的两个元素的大小

int(*)(const void* e1,const void* e2)中:

如果e1指向的元素大于e2指向的元素,那么函数返回>0的数字

如果e1指向的元素等于e2指向的元素,那么函数返回0

如果e1指向的元素小于e2指向的元素,那么函数返回<0的数字

3、qsort函数变量的详细介绍

1.void*base

base中存放的是待排序数组的第一个元素的地址

关于base的作用就是为了寻找到待排序的数组的地址,这里为什么使用void*指针呢?

void*指针,可以接收任意类型变量的地址。所以,这里我们使用void*指针来修饰base的目的是为了能够接收任意类型的数组。微软公司在创造这个函数的时候,是不知道使用者将要排序什么类型的数组,所以需要使用void*来修饰。

2.size_t num

num存放的是base指向的数组的元素个数

不管是冒泡排序,还是快速排序,我们都需要知道所要排序的元素个数,这个参数很好理解。

3.size_t size

size:size是base指向的数组中一个元素的长度(以字节为单位)

可能有些人很疑惑,为什么还需要知道数组中一个元素的长度呢?

这是由于base的数据类型是void*

如果我们是int*的话,向后看到的就是整型数组,如果我们是char*的话,向后看到的就是字符数组。但是我们使用的是void*指针,所以我们不知道数组中的元素的具体类型,所以我们需要传递

数组中一个元素的长度,如果排序的是整型的话,一个元素长度是4个字节,如果排序的字符类型的话,一个元素长度是1个字节。

如果没有size参数,给你一个空间,访问十个元素,那么访问一个元素的长度是多大呢?访问十个元素所要占的长度是多少呢?

c431f53a728f4d72a6c4648a9e1a883b.png

这就像是在路边询问路线,您需要到达一个地方。有人告诉您向前走十步就能到达,但他们没有说明一步应该走多远。或许他们每步迈的幅度较大,而您迈的幅度较小。因此,当您走了十步之后,可能会发现并没有到达目的地。

我们既需要知道访问多少个元素,也需要知道访问一个元素的长度才能够更加准确的访问空间。

4.int(*comper)(const void*,const void*)

先来分析一下int(*)(const void*,const void*)

首先,该参数是一个函数指针,它指向一个有两个无类型指针作为参数的函数,并且该函数的返回值是int类型的。

该函数指针的作用是将两个无类型指针指向的参数进行比较,如果参数1小于参数2返回小于0的整数,如果参数1等于参数2,返回0,如果参数1大于参数2,返回大于0的整数。

comper()函数的作用仅仅是比较两个参数的大小,并且通过返回值来告诉我们比较的结果,但是所比较的两个数是不能修改的。使用const修饰。

注意:使用qsort函数排序默认是升序

当我们得到的返回值>0的值时,qsort函数将会将这两个数字交换,当得到的返回值<0的值时,qsort函数将不会对其进行交换。

4、使用qsort函数排序整型数组,结构体数组

当我们了解了qsort函数的一些基础知识后,可以使用qsort函数来完成一些数据的排序;

4.1 使用qsort函数来排序整型数组:

#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;//通过相减来直接获得返回值的大小
}
void print_arr(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
void test1()
{
	int arr[10] = { 3,2,5,7,4,9,0,1,8,6 };//所排数组
	int sz = sizeof(arr) / sizeof(arr[0]);//元素个数
	qsort(arr, sz, sizeof(arr[0]), cmp_int);//qsort函数参数的传递
	print_arr(arr, sz);
}
int main()
{
	test1();
}

return *(int*)e1 - *(int*)e2这里通过相减可以直接获得返回值,如果e1>e2,返回>0的数,如果e1<e2, 返回<0的数,因此,使用qsort函数排序默认为升序,如果想要排逆序,只需要交换e1和e2的位置即可。

4.2 使用qsort函数来排序结构体数组:

//创建结构体变量
struct Stu
{
	char name[20];//人名
	int age;//年龄
};
void test2()
{
	struct Stu s[3] = { {"zhangsan",18},{"lisi",25},{"wangwu",20} };//创建结构体数组
	int sz = sizeof(s) / sizeof(s[0]);//获得数组元素个数
	qsort(s, sz, sizeof(s[0]), cmp_stu);

}
int main()
{
	test2();
}

 当开始调用函数cmp_stu来比较结构体数组时,这时候就会产生疑问,该按照什么来比较结构体大小,是按照名字字母顺序来比较?还是按照年龄来比较?

4.2.1 按照年龄来排序结构体数组:

cmp_stu_by_age(const void* e1, const void* e2)
{
	return (*(struct Stu*)e1).age - (*(struct Stu*)e2).age;
}
//e1.e2分别指向两个结构体对象

 (struct Stu*)e1这是将e1的类型强制转换为struct Stu*结构体类型。

完整代码:

#include <stdio.h>
#include <stdlib.h>

struct Stu
{
	char name[20];
	int age;
};
cmp_stu_by_age(const void* e1, const void* e2)
{
	return (*(struct Stu*)e1).age - (*(struct Stu*)e2).age;
}
void test2()
{
	struct Stu s[3] = { {"zhangsan",18},{"lisi",25},{"wangwu",20} };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);//qsort函数参数的传递
	for (int i = 0; i < 3; i++)
	{
		printf("%s,%d\n", s[i].name, s[i].age);
	}
}
int main()
{
	test2();
}

dd7bb03f9fa24a72a9abe50975f81274.png

 4.2.2 按照姓名来排序结构体数组:

在比较前,我们先了解一个函数strcmp函数,该函数的作用是用来比较字符串的大小

使用格式:strcmp(字符串1,字符串2)

如果字符串1 大于 字符串2,返回大于0的数字;

如果字符串1 小于 字符串2,返回小于0的数字;

我们知道名字是字符串,所以不能直接使用>比较,因此我们通过strcmp函数来比较大小

strcmp函数的使用需要包含头文件<string.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stu
{
	char name[20];
	int age;
};
cmp_stu_by_name(const void* e1, const void* e2)
{
	return strcmp((*(struct Stu*)e1).name , (*(struct Stu*)e2).name);
}
void test2()
{
	struct Stu s[3] = { {"zhangsan",18},{"lisi",25},{"wangwu",20} };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);//qsort函数参数的传递
	for (int i = 0; i < 3; i++)
	{
		printf("%s,%d\n", s[i].name, s[i].age);
	}
}
int main()
{
	test2();
}

 

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

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

相关文章

启动与登录Mysql

1.启动与停止MYSQL服务 启动MySQL 服务的命令 以管理员身份打开Windows 的命令行窗口&#xff0c;在命令提示符后输入以下命令启动MySQL 服务&#xff1a; net start[ 服务名称] 也可以直接输入以下命令&#xff1a; net start 按【Enter】键执行该命令&#xff0c;默认启…

测试网站dddd

Selenium PostmanpythonPytest

揭秘InnoDB:为何MySQL选择B+树作为索引结构

我们知道MySQL数据库InnoDB引擎索引的数据结构是B树&#xff0c;那他为什么不用红黑树&#xff0c;不用B树呢&#xff1f;用B树的优点在哪里&#xff1f;解决了些什么问题&#xff1f; 下面将以这几个疑问点为中心记录一下MySQL选用B树的原因。 揭秘InnoDB&#xff1a;为何MyS…

模型训练如何实现自动化输出评估报告、模型、特种平台

模型训练如何实现自动化 1、目标 把对文本分类【体育,教育,娱乐,经济,文学,政治】的模型实现自动化训练。 分类器:贝叶斯、支持向量机、梯度提升、随机森林、逻辑斯蒂回归 通过预设的准确率期望值与训练轮数,获取最优的分类器模型,当模型评估的准确率大于期望值时即…

Linux学习之路 -- 线程控制

前面我们介绍了线程的基础概念&#xff0c;即线程为进程内部的执行分支。下面我们将介绍一下具体的线程控制相关函数。 目录 1、铺垫 2、线程创建 3、线程等待 4、线程异常 5、线程退出 <1>线程函数返回退出 <2>pthread_exit <3>pthread_cancel 6、…

QT安装Qt Creater创建项目时无法选择Kit选项 No suitable kits found

1、安装QT时会遇到安装完qt&#xff0c;打开Qt Creater&#xff0c;新建工程时遇到无法选择Kit选项 No suitable kits found而无法下一步的问题。原因及解决方法如下&#xff1a; 2、原因&#xff1a; 因为在安装qt时&#xff0c;选择了错误的minGW&#xff0c;如下图&#xf…

【笔记】Java EE应用开发环境配置(JDK+Maven+Tomcat+MySQL+IDEA)

一、安装JDK17 1.下载JDK17 https://download.oracle.com/java/17/archive/jdk-17.0.7_windows-x64_bin.zip 2.配置环境变量 下载后&#xff0c;解压到本地&#xff08;目录中最好不要有中文或特殊字符&#xff09; 打开【控制面板】-【系统和安全】-【系统】-【高级系统…

Liunx:理解进程概念

一、进程概念 进程有两种可以理解的方式&#xff1a; 1、已经加载到内存中的程序&#xff0c;叫做进程。 2、正在运行的程序&#xff0c;叫做进程 从概念上挺好理解的&#xff0c;我们运行一个程序必然要通过CPU&#xff0c;所以自然需要加载到内存中…… 但我们应该关注的是&a…

Java反射:如何判断对象属性是否为static或final

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 在Java编程中&#xff0c;反射是一种强大的工具&#xff0c;允许在运行时检查类、接口、字段和方法的信息。通过反射&#xff0c;可以动态地创建对象、调用方法和访问字段&#xff0c;甚至可以修改私有字段的值。然而…

大模型:中国AI Agent应用研究报告2024

自2023年3月&#xff0c;以AutoGPT为代表的一系列技术框架的发布&#xff0c;Al Agent以其自主性和解决问题的能力&#xff0c;迅速获得科技圈各方讨论。并在之后一年多的时间中&#xff0c;陆续发布多项不同种类的技术框架。除了使用领域的探索之外&#xff0c;单智能体和多智…

2024华为OD统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++篇)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

大模型新书分享《大模型入门:技术原理与实战应用》(附PDF)

这本大模型书籍已经上传CSDN&#xff0c;朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】 新书速递 书名&#xff1a; 大模型入门&#xff1a;技术原理与实战应用 ISBN&#xff1a; 9787115638816 作者&#xff1a; 程絮森&#xff0c;杨波&am…

产品经理的发现和成长

获取更多资料&#xff0c;见下图

原装N9000B信号分析仪keysight/N9000B,N9000A详情参数

是德Keysight N9000B CXA 信号分析仪&#xff0c;多点触控&#xff0c; 特征&#xff1a; 9 kHz 至 26.5 GHz 的宽频率范围以及高达 25 MHz 的分析带宽让您了解更多 为手动和自动化制造测试系统添加可靠的信号分析 执行基本测量&#xff0c;例如杂散搜索和失真分析 使用可选…

1658.将x减到0的最小操作数

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;滑动窗口&#xff09; 题目要求从最左边或者最右边移除元素&#xff0c;需要思考两侧&#xff0c;这是比较麻烦的。 正难则反&#xff0c;我们逆向思维一下&#xff0c;最后剩余的元素是不是中间的连续区间&#xf…

人工智能 | Hugging Face 的应用

大纲 Hugging-Face 介绍 Hugging-Face 大语言模型 LLM 管理Transformers 机器学习框架文本生成推理 (TGI) Hugging Face Hugging-Face – 大语言模型界的 Github Hugging Face 专门开发用于构建机器学习应用的工具。该公司的代表产品是其为自然语言处理应用构建的 transfo…

网络编程(学习)2024.9.5

目录 网络协议头分析 MTU MSS 粘包和拆包 粘包 粘包原因 解决粘包 拆包 包头分析 以太网头 IP头 ​编辑 Tcp头 三次握手和四次挥手 三次握手 四次挥手 TCP可靠性的保证 1. 数据包顺序 2. 数据完整性 3.. 确认应答&#xff08;ACK&#xff09; 4. 重传机制…

springboot个性化大学生线上聊天交友系统

基于springbootvue实现的个性化大学生线上聊天交友系统 &#xff08;源码L文ppt&#xff09;4-017 4系统设计 4.1 软件功能模块设计 个性化大学生线上聊天交友分为两个模块&#xff0c;分别是管理员功能模块和用户功能模块。主要功能模块包括&#xff…

探索数据可视化的奥秘:Seaborn库的魔力

文章目录 探索数据可视化的奥秘&#xff1a;Seaborn库的魔力背景&#xff1a;为何选择Seaborn&#xff1f;Seaborn是什么&#xff1f;如何安装Seaborn&#xff1f;简单函数介绍与示例场景应用示例常见问题与解决方案总结 探索数据可视化的奥秘&#xff1a;Seaborn库的魔力 背景…

ApiOps Helper:本地代码智能扫描,API的注册管理自动化

APIOps Helper是什么 APIOps Helper是在IntelliJ IDEA平台上开发的插件&#xff0c;可以自动识别IDEA中Java项目的代码&#xff0c;从中扫描出API并自动生成OpenAPI规范文档。 用户可以选择将API导出为本地OpenAPI规范文档&#xff0c;或者将API同步到APIOps平台上进行API协同…