排序函数qsort和sort用法与区别简谈

       qsort和sort是两个编译器自带的快速排序方法,相比自己写一个排序算法,不仅更简单,效率也往往更高。qsort需要引入头文件<stdlib.h>,sort则需要<algorithm>。

       先说相对略微简单的sort,原型就不写了,直接举int数组的例子吧


int a[10] = {5,8,9,1,4,7,6,3,5,8};
sort(a,a+10,com); 

       其中有三个参数,a代表首元素地址(数组名就是首元素地址),a+10代表末元素后一位的地址,这两个参数表示了待排序的范围,所以也可以写a+1,a+5等等进行局部排序。第三个参数是个函数,如果省略默认按从小到大排序。接下来就举个自定义的比较函数com的例子。

bool com(int a,int b)    { return a < b; } 

       传递参数只能使用int直接传值,或者int&传递引用,不能int*传递指针。如果函数返回值为true,则不必交换元素,如果返回值为false,则进行交换,所以这个就是从小到大的排序啦。

       下面介绍qsort,为了体现两者的不同,这里举字符串的例子。

char* fruit[5] = {"apple","pineapple","banana","peach","melon"};
qsort(fruit,5,sizeof(fruit[0]),com);

       qsort需要四个参数,第一个仍然是首元素地址,第二个是元素数量,第三个是每个元素的大小,可以用sizeof(fruit[0])获取,因为fruit其实是个存储char*指针的数组,所以sizeof(char*)也可以,(注意:apple等字符串并不储存在fruit里面,而是在另一块内存,fruit只是存储了指向它们的指针,所以才能交换,如果写成char fruit[5][10],fruit就变成存储apple等字符串的数组了,而交换字符串是没有定义的, 会报错!!!),第四个参数是交换函数,省略也是默认从小到大排序。

       接下来是qsort和sort最大的不同,就是这个自定义的比较函数,其原型只有一种写法,返回值必须是int,参数不仅必须按引用传递,而且必须是void指针,不能具体写int*char*什么的,甚至连const都不能省略!!!要求可是比sort严格多

int com(const void* a,const void* b)    { return strcmp(*(char**)a,*(char**)b); }

       再看函数定义,首先看到的不同是,没有了>和<符号,还有就是一堆*。首先说和sort不同的是,qsort不再用>和<的真假判断是否交换,它一般用的是减法,例如比较两个int类型时要这么写,如果结果是负数就不用交换,如果结果是正数就进行交换。(按结果正负决定是否交换,而不是sort的真假!!!)于 strcmp也是这样,strcmp是<string.h>中的函数,用于比较字符串大小,如果a比b小结果是负数,a=b结果是0,a比b大 则结果是正数,所以说原理和int型没有区别。(第一个重要不同,一定要注意!如果两个函数的规则搞反的话就是瞎jb排了!)

return *(int*)a - *(int*)b;

       然后看那一堆*,因为qsort的比较函数com按地址传递,所以我们得到的a和b实际上是指向fruit元素的指针,而fruit元素本身又是指向apple等字符串的指针,所以a和b实际上是指向指针的指针,也就是char**型,(可以这么理解char*代表a指向的元素是 char*型,第二个*代表a是指针,连起来就是char**啦),所以首先要使用(char**)a类型转换为本来的模样,然后再进行解引用,所以*(char**)a其实就是fruit里的元素,由于是按指针传递,修改*(char**)a就等于修改fruit,所以又要求必须加const来保证不修改原数组。

      最后总结一下其实只要搞清楚两个重要区别就行啦,sort的比较函数按值或引用传递参数,然后根据com函数的返回值是true还是false决定是否交换,true不交换,false交换,为了匹配这个特性,一般用<>号判断大小。qsort的比较函数按void指针传递,所以多一部类型转换和解引用,然后根据com返回值的正负决定是否交换,负数不交换,正数交换,为了匹配这个特性,一般用减法判断大小。


  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
qsortqsort_s都是用于排序数组的函数,但它们在使用方式和安全性上有所区别。 1. qsort函数: - 用法qsort函数是C标准库中的一个函数,其原型为`void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))`。 - 参数解释: - `base`:指向待排序数组的首元素的指针。 - `nmemb`:待排序数组的元素个数。 - `size`:每个元素的大小(以字节为单位)。 - `compar`:比较函数的指针,用于定义元素之间的比较规则。 - 功能:qsort函数通过调用用户提供的比较函数来对数组进行排序排序结果将保存在原数组中。 - 注意事项:使用qsort函数时需要保证比较函数的正确性,否则可能导致排序结果不准确。 2. qsort_s函数: - 用法qsort_s函数是C11标准引入的安全版本排序函数,其原型为`errno_t qsort_s(void *base, rsize_t nmemb, rsize_t size, int (*compar)(const void *, const void *, void *), void *context)`。 - 参数解释: - `base`:指向待排序数组的首元素的指针。 - `nmemb`:待排序数组的元素个数。 - `size`:每个元素的大小(以字节为单位)。 - `compar`:比较函数的指针,用于定义元素之间的比较规则。 - `context`:用户自定义的上下文参数,可在比较函数中使用。 - 功能:qsort_s函数通过调用用户提供的比较函数来对数组进行排序排序结果将保存在原数组中。相比于qsort函数qsort_s函数提供了更多的安全性保障。 - 注意事项:使用qsort_s函数时,需要注意传入的参数必须符合安全性要求,否则可能导致运行时错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值