作为补充,还有另一种调用
qsort
的策略:创建一个中介
qsort
所需的原型函数,该函数调用启用类型比较函数。
#include <stdlib.h>
#include <stdio.h>
static int double_cmp(const double *d1, const double *d2)
{ return (*d1 > *d2) - (*d2 > *d1); }
static int double_void_cmp(const void *v1, const void *v2)
{ return double_cmp(v1, v2); }
int main(void) {
double p[] = { 2.18, 6.28, 3.14, 1.20, 2.72, 0.58, 4.67, 0.0, 1, 1.68 };
const size_t n = sizeof p / sizeof *p;
size_t i;
qsort(p, n, sizeof *p, &double_void_cmp);
for(i = 0; i < n; i++) printf("%s%.2f", i ? ", " : "", p[i]);
fputs(".\n", stdout);
return EXIT_SUCCESS;
}
尽管这样做存在问题,但可以将
double_cmp
用作其他非
qsort
事物的比较器。此外,根据我对
ISO 9899 6.3.2.3的解释,它不需要任何强制转换或显式赋值。
void指针可以转换为任何不完整或对象类型的指针......并再次转换回去。
qsort
中调用比较器函数,你会发现它调用了一个具有两个void *
指针的函数,所以这就是您的比较器函数必须是的内容。(如果所有数据指针类型都是“相同的”--当然,在当今流行的机器上它们都是相同的--错误的代码将会工作,但它仍然是错误的。) - Steve Summitvoid *
不在默认参数提升之列。这就是为什么传递给printf
的指向符合%p
格式说明符的指针必须明确转换为void *
的原因。 - dbushchar
字符,肯定会失败,因为Cray指针寻址64位字,并包含额外的内部字段来处理将char
数据打包到一个字中的情况。 - alephzero