【发布时间】:2021-04-11 08:06:56
【问题描述】:
qsort 和 bsearch 在 int 数组上的升序排序回调函数可能如下所示:
int ascending(const void *o1, const void *o2) {
int a = *(const int *)o1;
int b = *(const int *)o2;
return a < b ? -1 : 1;
}
然而,这个函数似乎违反了 C 标准中对 compar 函数的约束:
7.22.5.2
qsort函数概要
#include <stdlib.h> void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));说明
qsort函数对nmemb对象数组进行排序,base指向其初始元素。每个对象的大小由size指定。数组的内容根据
compar指向的比较函数升序排序,该函数使用两个指向被比较对象的参数调用。如果认为第一个参数分别小于、等于或大于第二个参数,则该函数应返回一个小于、等于或大于零的整数。如果两个元素比较相等,则它们在结果排序数组中的顺序是未指定的。
此比较函数是否正常或会导致未定义的行为?
【问题讨论】:
-
如果没有两个元素相等,那么是的。
-
bsearch 与 qsort 不同——你可以假设 bsearch 会检查等价性。
-
当然,比较函数的意图是对象必须与自身相等,因此如果
o1和o2指向相同,则正确设计的比较函数将返回相等(零)目的。此外,如果o1和o2指向具有相同字节的两个对象,我们希望它返回相等。一个更好的问题可能是,考虑到这样一个损坏的比较函数,是否有任何合理的排序算法在使用它时会失败? -
哦,顺便说一句,我认为这应该是一个合法的用例?
int dont_sort (const void *o1, const void *o2) { return -1; } -
a == b时会发生什么?您的函数将返回1,向qsort表明a大于b。这不会(可能)使排序操作无休止吗?
标签: c sorting language-lawyer qsort