除了dbush优秀的答案,需要注意的是,原型为int cmp(const char *s1, const char *s2)的替代比较函数的情况,比如strcmp,并没有那么清晰在问题中。 C 标准规定:
6.2.5 类型
[...] 指向void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。类似地,指向兼容类型的合格或不合格版本的指针应具有相同的表示和对齐要求。所有指向结构类型的指针都应具有彼此相同的表示和对齐要求。所有指向联合类型的指针都应具有彼此相同的表示和对齐要求。指向其他类型的指针不必具有相同的表示或对齐要求。
因此,指向具有原型 int cmp(const void *v1, const void *v2) 和 int cmp(const char *v1, const char *v2) 的函数的指针不兼容,但即使在 int cmp(const double *v1, const double *v2) 会出现问题的那些极其罕见的目标上,调用顺序也不太可能有所不同(早期的 Cray 系统和缺乏字节寻址能力的 CPU)。
您没有提供比较函数的代码:简单地返回值的差异是一个常见的错误 (*d1 - *d2)。这不适用于浮点值,也不适用于 int 值,因为减法可能会溢出。
这是一个适用于所有数字类型的递增顺序的实现:
int cmp(const void *v1, const void *v2) {
const int *p1 = v1, *p2 = v2;
return (*p1 > *p2) - (*p1 < *p2);
}
对于浮点类型,可能需要对 NaN 值进行特殊处理:
// sort by increasing values, with NaN after numbers
int cmp(const void *v1, const void *v2) {
const double *p1 = v1, *p2 = v2;
if (isnan(*p1)) {
return isnan(*p2) ? 0 : 1;
} else
if (isnan(*p2)) {
return -1;
} else {
return (*p1 > *p2) - (*p1 < *p2);
}
}