我是qsort()列表中的一些内存指针,以便稍后在函数中对它们进行bsearch。我的问题是,我是否需要键入将这些值转换为const void *之外的其他值来在C中进行合法比较?我可以做转换并让编译器告诉我,但我觉得这可能是编译器依赖的。
答案 0 :(得分:5)
比较很好,算术和解除引用不是(因为你不知道底层数据的大小)。所以是的,你可以很好地比较void 指针 (a)。
但是,请记住,除非要对其地址进行排序,否则通常不会比较传递给qsort
比较函数的指针。但是,因为它们已经按照那个顺序排序(作为一个数组),所以没有太多的用例: - )
您通常将void指针强制转换为特定指针,然后比较它们指向的内容。类似于:
int compfn (const void *p1, const void *p2) {
const char *str1 = *((const char **)(p1));
const char *str2 = *((const char **)(p2));
return strcmp (str1, str2);
}
您不必创建像str1
和str2
这样的临时工具(即使任何体面的编译器都会优化它们)。除了轻微的可读性问题外,没有任何问题:
int compfn (const void *p1, const void *p2) {
return strcmp (*((const char **)(p1)), *((const char **)(p2)));
}
(a)遵循正常规则,指针必须指向同一数组的元素或超出该数组的元素 - 其他任何内容都是未定义的。我提到完整性但是,如果你使用的是qsort
,那么无论如何你都会在数组上工作。
答案 1 :(得分:0)
通常你想在比较功能中做这样的事情
int compare(const void *a, const void *b)
{
int aa = *(int *)a;
int bb = *(int *)b;
return aa - bb;
}
并将void *转换为适当的类型(使用int只是一个例子)。
与const void *类型进行比较是有效的,但这是地址的比较。如果这是你想要的,那么如果没有上述(设计的例子)适用(取决于你所比较的),那就没问题了。
编辑:对于您的情况
int compare(const void *a, const void *b)
{
if (a < b) return -1;
else if (a == b) return 0;
return 1;
}
我这样做的原因是因为地址是sizeof(unsigned long),它大于int的大小,如果以某种方式溢出int,可能会导致问题。