备忘——C标准库中的qsort和bsearch

正好项目中需要排序和二分,懒得自己搞,就直接用C标准库中提供的函数了:

void qsrot(void *base, size_t num, sizt_t size, int(*cmp)(const void*, const void*));

void bsearch(const void *key, const void *base, size_t num, size_t size, int(*cmp)(const void*, const void*));

以上是两个函数的原型,简单的说明一下参数:

base表示数组首地址,无论qsort,还是bsearch只能操作数组,高级一点的说就是操作连续内存

num表示数组中元素的个数

size表示数组中每个元素的大小

key是bsearch特有的参数,表示我要从base数组中寻找一个怎样的值,但是key的数据类型是void*,bsearch又是如何知道key实际的值呢?下面我们着重介绍一下两个函数的核心:

cmp回调函数:

cmp回调函数需要传入两个const void *参数,还有一个int型的返回值

虽然两个函数都有这个cmp回调,但是意义不同,我们一个一个的说:

 

qsort中的cmp:

我们可以这样理解,第一个参数,我们叫做l(left),第二个参数,我们叫做r(right),这两个参数代表在以后的数组中,l元素一定在r元素的左边(与参数列表的相对位置一样,第一个参数在左,第二个在右),那么,我们的cmp函数就是做这样一个判断:我们是否接受这样一个顺序?如果接受,我们就返回-1,如果不接受,我们就返回1,如果我们认为两个元素相等,怎么排序无所谓,就返回0。

在得到这样的信息后,qsort在调用cmp时,发现返回值为-1,就什么也不做,发现返回值是1,就交换两个元素的位置,发现返回值是0,就按照最方便的方式,随便给个顺序。

举个例子来说:

如果回调函数写成:return *(int*)l - *(int*) r;的话

那么根据我们上面说的规则,如果l小于r,l-r的结果为-1,那么保持原有顺序,所以这样可以得到一个升序串,反之我们就可以得到一个降序串……

只要记住这一点,我们就可以将一些复杂的计算,按照我们的希望,将他们升序或者降序排序了……

 

bsearch中的cmp:

这里的cmp和qsort中的几乎完全不同,这里的cmp第一个参数,我们可以叫做key,也就是说,我们传给bsearch的第一个参数key,bsearch会很负责任的传给cmp做第一个参数……

那么,第二个参数呢?当然就是数组中其他的元素了,我们管它叫做element……

有人说,bsearch只能在升序的数组中使用,两个字概括——放屁!这表明他完全没用弄清楚cmp的作用……

实际上无论升序还是降序,只要是有序,我们就可以使用bsearch,用法也是非常的简单,当element不等于key时,如果我们希望继续在数组的左边找,就返回-1,如果希望继续在数组的右边找,就返回1,如果我们认为找到了,就返回0……

这里再介绍一个小技巧,就是bsearch中的key为const void*类型,这也就表明我们可以传常量值,当然是要加上必要的强制类型转换的……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值