1.qsort函数的用途
qsort函数作为c语言的库函数,用于数据的排序和分类
2.qsort函数的参数和返回值
我们可以访问相关网站查询相关信息
Input/Output - C++ Reference (cplusplus.com)
qsort函数第一个参数void* base指的是指向数组第一个元素的指针,并将这个指针强制类型转换为无类型指针,这么做的好处是能接收不同类型的数组,实现不同类型数据的排序,缺点是无类型指针不能进行+-解引用等操作
qsort函数第二个参数size_t num指的是指针指向的数组的元素个数,其中size_t 是(unsigned int,无符号整型)的缩写
qsort函数第三个参数size_t size指的是数组每个元素的大小,如果不知道具体的大小,可以使用sizeof(datatype),得到每个元素的大小。例如sizeof(int),得到的是数组中的一个整型元素的大小
qsort函数第四个参数int(*compar)(const void*,const void*)指的是指向一个函数的函数指针,指向的函数返回值是int 类型的,两个参数类型是const void*。注意:传的参数是自己写的函数,下面将会具体介绍
qsort函数的返回值是void,即该函数没有返回值
3.qsort 函数的具体运用
注:使用的编译器vs2022
首先我们创建了一个无序的数组,接着自己写了一个compare函数(注意:函数类型必须和qsort函数的形参一致),接着利用循环打印出数组的每个元素,结果如下:
我们发现数组成功排序。但是似乎我们对其原理一知半解,因此我们可以模拟实现这个函数加以理解
4.qsort函数的模拟实现
我们可以创建一个函数mysort来模拟实现qsort函数,为了方便我们将官方的函数形参和返回值拷贝一份。接着我们整体的思路就是冒泡排序,按照从小到大的顺序对数组的每一个元素两两比较
我们使用cmp和swap函数来实现比较和交换的功能,难点在于为了使各种类型的数组都能比较,我们使用void* base指针接收数组首元素,我们无法通过指针+-改变指针的位置,那我们如何进行前一个元素和后一个元素的比较呢?
也许有同学会想到可以将指针强制类型转换为某一具体类型来进行+-操作,但是我们不知道使用者传的是什么类型的数据,强制类型转换似乎不可行
但我们发现函数的参数size_t size似乎还没使用过,那么这其中肯定要用到它。我们发现不管传什么类型的数据,我们需要指针就一次跳过sizeof(datatype)个字节。因此我们可以将指针强制类型转换为char* 类型的指针,让其+size即跳过size个字节(即指针指向下一个元素),完美解决了数据不同所带来的问题,同时对下面cmp_int 函数也能有更深的理解
我们将指向第一个元素地址的指针和指向下一个元素地址的指针传给e1和e2,通过解引用操作得到对应的值再进行相减与0比较就可以得到它们的大小关系(注:如果是比较字符大小,比较的是ascll码值),上图是用来比较int类型的数据,同理下图是比较float类型的数据
接着我们实现交换(swap)的功能
我们用e1和e2分别接收指向第一个元素和下一个元素的指针,用size接收数组一个元素的大小。接着我们通过指针的解引用和指针的移动将size个字节的内容一一交换,实现数组一个元素的交换
接着我们可以测试下我们的成果是否符合预期
结果符合预期
5.qsort总结
qsort作为c语言的分类排序函数,对处理数组的数据具有重要帮助,与此同时通过qsort的模拟实现,我们对qsort函数有更深的理解,希望该文对大家有所帮助!