返回介绍

用函数指针设置顺序

发布于 2024-10-10 23:21:30 字数 3450 浏览 0 评论 0 收藏 0

可能你已经猜到了答案:C 标准库的排序函数会接收一个比较器函数(comparator function)指针,用来判断两条数据是大于、小于还是等于。

qsort() 函数看起来像这样:

qsort() 函数会反复比较两个数据的大小,如果顺序颠倒,计算机会交换它们。

这就是为什么要使用比较器函数。它会告诉 qsort() 两个元素哪个排在前面,它会返回三种值:

下面来看一个例子,看看比较器函数在实际情况中是如何工作的。

int 排序聚焦

假设有一个整型数组,你想升序排列它们,比较器函数应该长什么样子?int scores[] = {543,323,32,554,11,3,112};
你观察 qsort() 接收的比较器函数的签名,会发现它接收两个 void* ,也就是两个 void 指针。我们在使用 malloc() 时碰到过它,void 指针可以保存任何类型数据的地址,但使用前必须把它转换为具体类型。qsort() 函数会两两比较数组元素,然后以正确的顺序排列它们。qsort() 通过调用传给它的比较器函数来比较两个元素的大小。int compare_scores(const void* score_a, const void* score_b){ ...}



值以指针的形式传给函数,因此要做的第一件事就是从指针中提取整型值。如果 a 大于 b ,需要返回正数;如果 a 小于 b ,就返回负数;如果相等,返回 0 值。对整型来讲这很简单,只要将两数相减就行了:下面是用 qsort() 排序这个数组的方法:qsort(scores, 7, sizeof(int), compare_scores);

 

练习

现在轮到你了,下面描述了几种不同的排序,你能为每种排序编写比较器函数吗?为了帮你,第一个比较器函数已经写好了。最后,假设你已经有了 compare_areas() 和 compare_names() ,下面两个比较器函数你会怎么写?

 

练习解答

现在轮到你了,下面描述了几种不同的排序。请为每种排序编写比较器函数。最后,在已经有了 compare_areas() 和 compare_names() 的前提下,下面两个比较器函数你会怎么写?

 

轻松一刻

即使你被这题难倒了也不用担心。本题涉及指针、函数指针,甚至还有一些数学,如果你觉得很难,那就休息一下,喝两口水,过一两小时以后再来试试。

试驾

有几个比较器函数确实比较难写,有必要运行一下。需要用以下代码调用比较器函数。

编译并运行代码,将得到:

太棒了,代码工作了!

现在试着写一些你自己的代码吧。排序函数很有用,比较器函数却很难写,不过熟能生巧,多写几个就会了。这里没有蠢问题问:用来给字符串数组排序的比较器函数使用了 char** ,它是什么意思?答:字符串数组中的每一项都是字符指针(char* ),当 qsort() 调用比较器函数时,会发送两个指向数组元素的指针,也就是说比较器函数接收到的是指向字符指针的指针,在 C 语言中就是 char** 。问:当调用 strcmp() 时,为什么是 strcmp(*a, *b) 而不是 strcmp(a, b) ?答:a 、b 的类型是 char** ,而 strcmp() 函数需要接收 char* 类型的值。问:qsort() 会创建新数组吗?答:不会,qsort() 在原数组上进行改动。问:为什么我的头有点疼?答:别担心,指针很难用,如果你一点儿也不感到困扰,可能是想得还不够深。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文