C 对指针数组进行排序
我认为,为了对指针数组进行排序,可以将指针视为int吗C 对指针数组进行排序,c,sorting,pointers,C,Sorting,Pointers,我认为,为了对指针数组进行排序,可以将指针视为int吗 qsort(ptrs, n, sizeof(void*), int_cmp); 我想对ptr进行排序,以确定是否存在任何重复项,而不管指针指向的是什么类型的对象,因此qsort是这样做的前提 我的int\u cmp()非常标准,例如 int int_cmp(const void *a, const void *b) { const int *ia = (const int *)a; // casting pointer types
qsort(ptrs, n, sizeof(void*), int_cmp);
我想对ptr进行排序,以确定是否存在任何重复项,而不管指针指向的是什么类型的对象,因此qsort是这样做的前提
我的int\u 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可能会在我可能忽略的情况下导致问题?不,你完全不对,除非你想按地址对指针排序。然而,实际地址很少有任何意义,所以这是不太可能的 为了检测重复的指针,您应该只比较指针本身,这是定义良好的 我可能会使用
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;
}
static int order_指针(const void*pa,const void*pb)
{
常数a=*(void**)pa,b=*(void**)pb;
返回ab;
}
我还没有测试过这个,但是类似的东西应该可以用
由于无法有效比较随机指针,因此有必要将其转换为uintptru\t
。我引用C99标准草案第6.5.8.5节:
比较两个指针时,结果取决于指针中的相对位置
指向的对象的地址空间。如果两个指向对象的指针或两个类型都不完整
指向同一对象,或同时指向同一数组对象的最后一个元素,
他们比较平等。如果指向的对象是同一聚合对象的成员,
指向后来声明的结构成员的指针比指向成员的指针大
在结构的前面声明,并指向具有较大下标的数组元素
值比指向下标较低的相同数组元素的指针大
价值观指向同一联合对象成员的所有指针比较相等。如果
表达式P指向数组对象的元素,表达式Q指向
同一数组对象的最后一个元素,指针表达式Q+1大于
P.在所有其他情况下,行为未定义。
我把最后一句加粗了,因为这在这里是适用的 如果您使用比较,而不是减法,您可以使用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 ;
}
int-int\u-cmp(常数无效*pa,常数无效*pb)
{
常数void*a=*(void**)pa;
常数void*b=*(void**)pb;
如果(ab)返回1;
返回0;
}
不,不能将指针视为int
。指针的大小可能与int
的大小不同。还要记住,有许多类型的数据不能直接比较,也不能用在算术表达式中(例如结构)。保证能够保存指针的唯一整数变量是intptr\u t
和uintptr\u t
。应该是const int*ia=*(const int**)a;常数int*ib=*(常数int**)b代码>那么,当一个int
数组而不是int*
数组时,你会怎么做?我的示例cmp函数用于一个int数组:指针数组,例如qsort(ptrs,n,sizeof(void*),int\u cmp);用于指针数组的int\u cmp
。是的,这正是我想要做的-按地址排序,以便评估数组中是否有重复的PTR,例如,2个相同的地址为什么要转换为整数?请参阅TripeHound的答案。@alk因为未定义的行为。:)我很高兴我问了最初的问题-毕竟不是那么简单。。我可能应该发布一个更大的问题,“如何以一种通用的方式从一个PTR数组中移除重复的PTR,即指向相同底层对象的PTR,而不依赖于底层对象。@unwind作为一个旁白,您的默认方法是使函数成为静态的吗?”?我原以为您会希望在许多文件中使用这样的cmp函数?-1,这是未定义的行为。不是为了吹响我自己的号角,但是。。。请看我的答案。@alk Yes,除非你知道指针指向(或刚好超出)同一个“对象”,请看我答案中的标准引文。@REWIND:我不研究(或阅读)标准,所以我很乐意向更深的知识低头,但如果比较两个可能指向任何东西的指针是未定义的,如何将它们转换为整数才能得到更好的定义?@TripeHound C不能保证指针只编码为普通整数。例如,可能存在分段内存。对于这样的体系结构,编译器必须在转换为整数时插入聪明度,以“展平”空间,使不同的指针变成不同的整数。据我所知,整数之间的比较是没有限制的。在[this_answer]{}中,他们引用了:在C99中,它被定义为“一种无符号整数类型,其属性是任何指向void的有效指针都可以转换为这种类型,然后再转换回指向void的指针,结果将与原始指针相等”。那么,这是否意味着比较intptr\t也没有定义(您所能做的就是将它们转换回void指针?)