我认为将指针视为int以便对指针数组进行排序是正确的,例如。
qsort(ptrs, n, sizeof(void*), int_cmp);
我想对ptrs进行排序,以确定是否存在任何重复项,无论指针所指向的是什么类型,因此qsort是这样做的前提。
我的int_cmp()
非常标准,例如
int int_cmp(const void *a, const void *b)
{
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
/* integer comparison: returns negative if b > a
and positive if a > b */
return *ia - *ib;
}
它似乎可以在我的单元测试中工作但是有一些原因可以解释为什么将ptr视为int可能会导致我可能忽略的这种情况出现问题?
答案 0 :(得分:3)
不,你根本不对,除非你希望按地址对指针进行排序。实际的地址很少有任何意义,所以这是不太可能的。
为了检测重复指针,你应该只是比较指针,这是明确定义的。
我可能会使用uintptr_t
:
static int order_pointers(const void *pa, const void *pb)
{
const uintptr_t a = *(void **) pa, b = *(void **) pb;
return a < b ? -1 : a > b;
}
没有测试过这个,但是这样的事情应该有用。
转换为uintptr_t
是必要的,因为您无法有效地比较随机指针。我提出了C99标准草案,§6.5.8.5:
当比较两个指针时,结果取决于中的相对位置 指向的对象的地址空间。如果有两个指向对象或不完整类型的指针 指向同一个对象,或者两者都指向同一个数组对象的最后一个元素, 他们比较平等。如果指向的对象是同一聚合对象的成员, 稍后声明的结构成员的指针比指向成员的指针要大 在结构中先前声明,并指向具有较大下标的数组元素 值的比较大于指向具有较低下标的相同数组的元素的指针 值。指向同一个union对象的成员的所有指针都比较相等。如果 表达式P指向数组对象的元素,表达式Q指向 同一个数组对象的最后一个元素,指针表达式Q + 1比较大于 P. 在所有其他情况下,行为未定义。
我把最后一句加粗,因为这是适用的。
答案 1 :(得分:2)
如果你使用比较而不是减法,你可以坚持使用void指针:以下是一个简单的测试:
int int_cmp( const void *pa, const void *pb )
{
const void* a = *(void**)pa ;
const void* b = *(void**)pb ;
if( a < b ) return -1 ;
if( a > b ) return 1 ;
return 0 ;
}