详解c语言中的qsort函数(有图)

目录

目录

一、qsort函数是什么

       1、自定义冒泡函数时遇到的问题

       2、qsort函数的作用

       (1)int整形数组排序(2)浮点型数组排序(3)字符数组排序

       (4)结构体排序       

二、qsort函数的原理解析

     1、对qsort定义的函数参数类型拆分理解

      2、qsort的原理

三、模拟实现qsort函数


写在前言之前: 本人是大一新生,写的东西难免有不足之处(比如不会写目录)。

                          如有错误,欢迎指出。


前言:大家学习时遇到不懂的地方,可以先问问度娘

如果你觉得查百度会拉低程序员的逼格的话,可以用下面这个网站

cpulspuls

在"Search"里输入想要查找的函数,就可以看到它的定义和使用案例了。


一、qsort函数是什么

1、自定义冒泡排序函数时遇到的问题:

 在正式介绍qsort函数之前,我先说一下我自己写代码时遇到的问题

void bubble_sort(int arr[], int sz)
// int arr[]把类型写死了,只能排int类型的数
{//数组有i个元素,总共要进行i-1趟排序int i = 0;for (i = 0; i < sz - 1;i++) {//第一趟比较i-1次//第二趟比较i-2次……int j = 0;for (j = 0; j < sz - 1 - i;j++) {if (arr[j]>arr[j+1]) {int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}
int main() {int arr1[10] = { 2,1,6,3,4,5,8,7,9,10 };int sz = sizeof(arr1) / sizeof(arr1[0]);bubble_sort(arr1, sz);
}

很明显:我写的bubble_sort函数只能排序int类型的数组

 c语言中难道就没有一个可以排序大部分类型的库函数吗?

答案是有的,就是qsort函数


位置:qsort函数位于头文件<stdlib.h>

2、qsort函数作用

如何实现升序或者降序呢?答案是通过改变自己写的compar函数实现

//升序
int compar_float(const void* p1, const void* p2) {return (int)*(float*)p1 - (int)*(float*)p2;
}//降序
int compar_float(const void* p1, const void* p2) {return (int)*(float*)p2 - (int)*(float*)p1;
}

(1)int整形数组排序

                                            打印数组的函数

int compar_int(const void* p1, const void* p2) {return *(int*)p1 - *(int*)p2;//强制类型转换 
}

                                             qsort函数和它指针指向的函数

#include<stdio.h>
#include<stdlib.h>void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++) {printf("%d ", arr[i]);}
}int main() {int arr[10] = { 2,1,6,3,4,5,8,7,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);// 用数组的字节大小/数组中每个元素的大小计算元素个数qsort(arr,10,sizeof(arr[0]), compar_int);print(arr, sz);//这是我写的打印数组的函数
}

这样,arr数组就成功按照升序排序了


(2)浮点型数组排序 

int compar_float(const void* p1, const void* p2) {return (int)*(float*)p1 - (int)*(float*)p2;
}int main() {float arr[] = { 5.0f,3.0f,4.0f,3.5f };int sz = strlen(arr);qsort(arr, sz, sizeof(arr[0]), compar_float);
}

理论上可以,但不知道为什么运行不了 


(3)字符数组排序

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
int compar_char(const void* p1,const void* p2) {return strcmp((char*) p1,(char*)p2);
}int main() {char arr[] = "hello";//排列字符串的顺序,本质上是排列它们的asc2码值int sz = strlen(arr);//strlen计算长度,找到'\0'就停止//如果用sizeof计算arr的长度,就要-1//因为sizeof计算是包括了'\0'qsort(arr,sz,sizeof(arr[0]), compar_char);printf("%s\n",arr);
}

大致介绍一下strcpm函数   

作用:用于比较两个字符串是否相等

还是用例子说明

#include<stdio.h>
#include<string.h>
int main() {char arr1[10] = "abbcd";char arr2[10] = "abcd";int ret = strcmp(arr1,arr2);printf("%d\n",ret);   //结果为-1
}

 原理:

 如果 str1>str2 返回正数    如果 str1<str2 返回负数  

 如果 str1==str2 &&str1=="\0"&&str2=="\0"  返回0

注:在vs中,这个函数只会返回1,-1,0


顺便附上一张asc2码值表


(4)结构体排序

struct student {char name[10];int age;
};//比较的是结构体变量的年龄
int compar_age(const void* p1, const void* p2) {return ((struct student*)p1)->age - ((struct student*)p2)->age;
}int main() {struct student s[3] = { {"xiaoming",10},{"zhangsan",16},{"kangkang",14} };int sz = sizeof(s) / sizeof(s[0]);qsort(s, sz, sizeof(s[0]), compar_age);
}

 排序成功

美中不足的是,我在改变排序对象的类型时,还是要更改compar函数,不能实现“一劳永逸”的目标


二、qsort函数的原理解析

1、对qsort定义的函数参数类型拆分理解

首先,我们先来了解qsort函数的定义

void*是空指针,如果暂时不知道要用什么类型存放数据,可以先用void*,再强制类型转换。

优点:可以存放多种数据

缺点:不能解引用,不能+数字

 还是用代码举例

int main() {int a = 1;void* pa = &a;pa+1;  //error*pa = 2;  //error
}

size_t 本质上是一种无符号整形

 int (*compar)(const void*,const void*)  表示一个函数指针。

这个参数的作用是将compar函数的地址传给qsort函数。

这也就是为什么我们在使用qsort函数时还要自己写一个比较函数


2、qsort函数的原理

首先,我们先来认识下qsort函数定义的中文意思

qsort(数组首元素的指针,数组的元素个数,每个数组元素所占的字节大小,自己设置的比较函数)

在解释原理之前,我们需要先了解一种排序方法:冒泡排序

假设我们要升序下面的数组

int arr = {9,8,7,6,5,4,3,2,1};

第一趟我们有9个数字参与排序,一共比较了8次

以此类推:第二次 有8个数字进行了排序 一共比较了7次

……

总结:若有i个数字参与排序,总共要排序i-1,每一趟比较的次数都会递减,

次数从i-1开始 

   关于升序或者降序的解释:  

将棕色方框内的第一个元素减去第二个元素,得到的结果>0,这时,compar函数的返回值就会是正数。qsort函数接受到这个返回值时,会判断它的正负性。如果它是正数,就会交换棕色方框内数字的位置。这就是升序的原理。      

  如果要是排序方式变为降序,那就要使返回值变为负数,具体实现方式就是将第一个元素减去第二个元素改为第二个元素减去第一个元素,也就是更换减数和被减数的位置。

  不难发现:compar函数的一个重要作用,就是决定qsort函数是升序还是降序,具体通过返回值的正负来实现

 qsort函数排序的原理,就是将输入的数组进行冒泡排序。


有的人可能会疑惑:qsort函数为什么要有“元素的字节大小”这一个参数呢?

在使用冒泡排序时,我们需要找到某个数组元素及其下一个数组元素的地址

但是,在设计qsort函数时,设计者不知道使用者会排序什么类型的元素。

   再次回看定义,我们发现,设计者也想到了这一点:

base元素类型为void*,这意味着我们可以把base的类型设置为int* ,char*,long* 等等。

但是,问题就出现了

int main() {int arr[5] = { 1,2,3,4,5 };void* parr = &arr;*(parr + 1) = 5; //这么写报错了
}

虽然void*就像垃圾桶一样,可以存放不同类型的数组,但却很难直接找到数组对应的元素。

借助强制类型转换,可以解决这个问题。我们先来看一看下面的例子

 

注:数组名一般情况下表示数组首元素的地址,但有两种情况下不是:

1、sizeof(数组名) //这表示数组所有元素的字节大小

2、&数组名 //这表示整个数组的地址 

 对上面图片的解释:

不难发现:上图中红色的数字正好对应这个元素在数组中的下标,而蓝色的数组正好对应这个元素的字节大小。

在模拟实现的过程中,我们能不能用一个变量表示红色的数字,用另一个变量表示蓝色的数字呢?


三、模拟实现qsort函数

  

我们发现,模拟qsort函数的需要实现的功能有:1、对数组进行冒泡排序 2接受compar函数的返回值,以实现升序和降序。难点有:模拟的函数需要兼容各个类型的元素。

void swap(char* e1, char* e2, int width) {int i = 0;for (i = 0; i < width; i++) {char tmp = *e1;*e1 = *e2;                     //这是用来交换数组中相邻数字的函数*e2 = tmp;e1++;e2++;}
}int sort_int(const void* p1, const void* p2) {return *(int*)p1 - *(int*)p2;      //这是我们自己写的compar函数
}void my_qsort(void* base, int sz,         //这是模拟的qsort函数        int width,//一个元素所占的字节大小int (*compar)(const void* p1, const void* p2))
{//如果数组有i个数字,共排序i-1趟int i = 0;for (i = 0; i < sz - 1; i++) {int j = 0;for (j = 0; j < sz - 1 - i; j++) {//这里在比较相邻数字的大小,以决定要不要交换if (compar((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}
}//这里是整个程序的入口
int main() {int arr[10] = {8,2,4,3,7,9,1,10,5,6};int sz = sizeof(arr) / sizeof(arr[0]);my_qsort(arr,sz,sizeof(arr[0]),sort_int);

有了上面的铺垫,相信理解起这一段代码也就不难了

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

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

相关文章

qsort函数详情

文章目录 一.qsort函数的使用1.qsort函数定义&#xff1a;2.使用 二.qsort函数的模拟实现 一.qsort函数的使用 1.qsort函数定义&#xff1a; qsort函数实现的功能为&#xff1a;对一组数据进行排序。 表现形式&#xff1a; void qsort(void *base, size_t num, size_t size,…

qsort函数

目录 1.什么是qsort函数2.实现一个qsort函数3.用qsort函数排序一个结构体4.模仿qsort的功能实现一个通用的冒泡排序 1.什么是qsort函数 我们以前学习过的一些排序算法&#xff0c;如冒泡、希尔、快排等等&#xff0c;它们速度有快有满&#xff0c;但是这些排序都只能排序一种类…

qsort函数的使用方法

前言 qsort函数是C语言库函数内给我们提供的一个可以实现排序的函数 它不仅可以排序数组&#xff0c;还可以排序字符串&#xff0c;以及结构体类型 下面是qsort函数的使用方法以及注意事项 一、了解qsort函数 根据MSDN提供的参数 由此我们可以知道 使用qsort函数需要引用头文…

简单介绍一下qsort函数

目录 一.回调函数 二.qsort函数 三.void*指针 四.用qsort函数进行升序排序 1.整形数组排序 2.结构体数组排序 3.字符数组排序 五.使用冒泡排序模拟实现qsort函数 一.回调函数 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针&#xff08;地址&#xff09;…

C语言qsort函数的使用详解

文章目录 一、qsort函数简介1.函数原型2.参数含义3.比较函数详解 二、比较函数使用案例1.整型数组2.字符数组3.double型数组4.字符串1.按字符串首字母进行排序2.按字符串长度进行排序3.按字典进行排序 5.结构体 三、qsort函数完整使用案例1.整型数组2.字符数组3.double型数组4.…

qsort函数用法 + 模拟实现qsort函数

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言学习者 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞…

C语言qsort函数用法

qsort函数简介 排序方法有很多种&#xff1a;选择排序&#xff0c;冒泡排序&#xff0c;归并排序&#xff0c;快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。因为他速度很快&#xff0c;所以系统也在库里实现这个算法&#xff0c;便于我们的使用。 这就…

qsort函数讲解

qsort函数的作用是将所有数据排序&#xff0c;那么它和普通的冒泡排序或者选择排序有什么区别呢&#xff1f;它不仅仅可以排序数组中的数字&#xff0c;还可以排序结构体。当然升序和降序它都支持&#xff0c;不过输入参数的顺序会有所不同&#xff0c;下面我们来详细讲解一下这…

【C语言】qsort函数的使用和模拟实现

本篇文章我们来了解一下回C语言中qsort函数的使用方法和模拟实现。这是一个通用性很强而且非常方便的库函数&#xff0c;通过这篇文章希望能让你了解sort函数。 目录 一、qsort的介绍&#xff1a; 二、qsort函数的使用 1.qsort排序整形 2.qsort排序字符串 3.qsort排序结…

C语言之——快速排序qsort库函数的讲解

qsort函数C语言编译器函数库自带的排序函数&#xff0c;也叫快速排序函数。之前我写过一篇关于冒泡排序的代码讲解&#xff0c;大家感兴趣的话可以先看一看我对于冒泡排序的讲解。 相比较于冒泡排序&#xff0c;快速排序可以用更加快捷的速度去排列升降序&#xff0c;它的时间复…

C语言qsort函数使用方法大全

文章目录 一、qsort函数简介二、qsort函数常用实例1.比较整型数组2.比较char数组3.比较double数组4.比较字符串4.1按首字母排序4.2按长度排序4,3按字典顺序 5.结构体排序5.1 多级排序 三、qsort深度剖析 一、qsort函数简介 排序方法有很多种&#xff1a;选择排序&#xff0c;冒…

C语言-qsort函数详解

目录 一.qsort函数是什么 二.使用qsort排序-以升序为例 关于void*型指针&#xff1a; 1.整形数组排序 2.字符数组排序 3.字符指针数组排序 4.结构体数组排序 5.浮点型数组排序 三.使用冒泡排序思想模拟实现qsort函数 1.什么是冒泡排序&#xff1a; 2.冒泡排序代码 3. …

C语言qsort()函数的使用(详解)

目录 1.参数含义 1.首元素地址base 2.元素个数num 3.元素大小size 4.自定义比较函数compar 2.使用方式 1.头文件 2.compar的实现 3.整体代码 qsort&#xff08;&#xff09;函数&#xff08;quick sort&#xff09;是八大排序算法中的快速排序&#xff0c;能够排序任意…

虚幻4地形怎么增加层_虚幻周报20200407 | 在家也要好好工作呀~

官方知乎号&#xff1a;虚幻引擎 搜集日期&#xff1a;20200330-20200405 整理编辑&#xff1a; 大钊&#xff0c;小辉辉&#xff0c;马古斯&#xff0c;小帅帅 声明&#xff1a;文档搜集来自网上&#xff0c;难免遗漏&#xff0c;请联系我们投稿和添加关注。该文档版权归整理…

2020年笔记本电脑选购指南

**本文首发微信公众号陈蛋蛋碎碎念&#xff0c;获取更多软件、教程、模板资源&#xff0c;请关注公众号。 最近在群里有小伙伴问关于选购电脑的事&#xff0c;毕竟开学季又要到了。刚好蛋蛋现在又在3C公司工作&#xff0c;所以平时也需要了解这方面的知识&#xff0c;于是就准…

[转]Warzone 2100(战争地带2100)

发行公司&#xff1a;Eidos Interactive 开发公司&#xff1a;Pumpkin Studios 游戏类型&#xff1a;即时战略 游戏语言&#xff1a;英文 发行日期&#xff1a;1999 年4月 系统操作&#xff1a;Win95以上 伴随着这部来自英国开发公司Pumpkin Studios的作品&#xff0c;1999年…

显卡优化软件测试面试,是吹嘘还是真有用?NV游戏优化软件测试

1前言&#xff1a;NVIDIA游戏优化软件试用 英伟达真实热衷为用户提供出色的游戏方案&#xff0c;日前发布了一款GeForce Experience的新软件&#xff0c;本质上是一个基于云端的服务&#xff0c;旨在分析你的硬件并自动调整显示分辨率和游戏设置&#xff0c;以提供更好更优化的…

【转】为什么中国不会有3A游戏

编&#xff1a;王妙一&#xff0c;游戏开发者&#xff0c;代表作《WILL&#xff1a;美好世界》&#xff0c;曾获第二届PlayStation开发者大赛冠军。王妙一大学时就读于清华软件学院图形研究所&#xff0c;本文将从游戏图形技术的发展变迁开始&#xff0c;谈谈3A游戏在现今&…

FPS游戏

FPS 求助编辑百科名片 FPS FPS是第一人称射击类游戏的简称&#xff08;游戏专有名词&#xff09;。 FPS&#xff08;First-Person Shooter Game&#xff09;&#xff1a;第一人称射击游戏 严格来说FPS属于ACT类游戏的一个分支&#xff0c;但和RTS类游戏一样&#xff0c;由于其在…

Centos6.5环境Nginx 1.16.1升级到1.24.0版本

一、背景 2023年4月11日&#xff0c;官方发布了Nginx最新稳定版&#xff0c;版本号为 1.24.0。该版本是基于1.23.x&#xff08;1.23.0 - 1.23.4&#xff09;开发版的Bug修复&#xff0c;以及一些新特性的加入&#xff0c;而形成的稳定版。安全部门扫描后&#xff0c;发现现场不…