Bootstrap

【C语言入门篇】C语言qsort函数解析(详细易懂)

【C语言入门篇】C语言qsort函数解析(详细易懂)

 🌈个人主页:开敲

🔥所属专栏:C语言

🌼文章目录🌼

1.qsort函数的作用

2.qsort函数如何使用

3.扩展

4..总结

1.qsort函数的作用

  qsort函数是C语言中的一种排序函数,可以排序不同类型的数组:结构体、字符串、整型等,其使用的排序方法为快排(快速排序),使用qsort函数需要包含<stdlib.h>的头文件。

2.qsort函数如何使用

  在调用qsort函数时,我们需要传参,参数部分就是qsort函数的核心,下面来看一段代码

这段代码我们创建了一个整型数组,并计算了数组的长度,接下来就是调用了qsort函数,重点就在于调用qsort函数时的传参。第一个参数arr就是数组的首元素地址,也就是将需要排序的数组传给了qsort函数。第二个参数sz就是数组的长度(元素个数),将需要排序的数组的元素个数传给qsort函数。第三个参数sizeof(arr[0])是单个元素的长度。第四个参数是一个函数,这个函数需要我们重点来讨论。

首先先来讨论前三个实参。下面来看看qsort函数的声明

第一个形参void* base用于接收arr数组的地址。至于为什么是void*类型,这是因为在我们实际创建数组的时候,qsort函数并不知道我们创建的是什么类型的数组,可能是结构体、字符串、整型等类型,因此qsort在接收时只能用void*类型来接收,因为void*类型不指向任何一个类型,可以用于接收不同类型。

第二个形参suze_t num是无符号整型参数,用于接收数组的元素个数。

第三个形参size_t size也是无符号整型参数,用于接收数组单个元素的长度。

最后一个形参需要我们重点来讨论。int(*compar)(const void*,const void*)是一个函数指针,返回类型是int型,参数部分也是void*类型,同样也是为了接收不同类型(这里也可以写成(const void* e1,const void* e2),为了方便讲解,我们后面就写成(const void* e1,const void* e2)),这个函数指针指向的函数需要我们自己来定义

这里的cmp就是我们自己定义的函数。这个函数有什么作用呢?

首先我们知道,排序分为升序和降序,在实际中我们可以根据不同的需要来进行排序。但是,qsort函数并不知道我们想要排为升序还是降序,那么如何让他知道呢?这就是cmp_int函数的职责了。首先我们要知道,e1和e2分别指向数组中相邻的两个元素(这里也就可以解释为什么类型时void* 了,用于接收不同类型的元素),那么这里的return *(int*)e1-*(int*)e2是什么意思呢?来看看cplusplus中对于qsort函数的解释

这里一大堆英文的意思就是:

1.当p1(e1)所指向的元素 < p2(e2)所指向的元素时,返回一个<0的数

2.当p1(e1)所指向的元素 = p2(e2)所指向的元素时,返回0

3.当p1(e1)所指向的元素 > p2(e2)所指向的元素时,返回一个>0的数

当返回的数 > 0时,由qsort函数对指向的两个数进行排序。返回的数 <= 0时,不进行排序。

知道了这个,我们再回到上面的代码

这里return *(int*)e1-*(int*)e2就是看看e1和e2(e1指向元素在e2指向元素之前)所指向元素的大小关系。那为什么要把e1、e2强制类型转换为(int*)呢?这是因为,void*类型不指向任意一个类型,因此,在实际中不能直接将他们解引用进行操作,而我们创建的数组是int类型的,因此我们可以强制类型转换为(int(*)。这个函数的作用就是让qsort函数知道我们需要排成升序还是降序,这里是将数组排为升序。如果要排为降序只需要

将e1、e2交换位置即可。

下面来看看执行结果

3.扩展

  上面说过,qsort可以排序不同类型的数组,下面我们来排序字符串类型的数组以及结构体类型的数组。

                                                                      1.字符串

 2.结构体(根据名字排序)

                                                         3.结构体(根据年龄排序)

补充:strcmp是用于字符比较的函数

4..总结

  qsort函数是一个排序函数,使用时需要包含<stdlib.h>的头文件,在传参时,需要传入数组的地址,数组的元素个数,数组单个元素的长度,以及排序判断函数。

;