所以我在c中使用qsort(),我的比较函数通常包括创建一个正确类型的指针并从参数中赋值。是否可以只从参数中转换指针而不创建新的指针? 如果是的话,我做错了什么?
struct date_t{
int time;
int dob;
};
/* the old working function
int cmpfunc (const void * one, const void * two) {
struct date_t *itemtwo=two;
struct date_t *itemone=one;
return itemone->time-itemtwo->time;
}
*/
int cmpfunc (const void * one, const void * two) {
return (struct date_t*)(one)->time - (struct date_t*)two->time;
}
我得到了:
main.c:17:30: warning: dereferencing 'void *' pointer
return (struct date_t*)(one)->time - (struct date_t*)two->time;
^~
main.c:17:30: error: request for member 'time' in something not a structure or union
编辑:
我用
进行编译int cmpfunc (struct date_t *one, struct date_t *two) {
return one->time - two->time;
}
但是,我怎么会用演员表来做?
答案 0 :(得分:2)
类型转换操作符()
的优先级低于指向成员的操作符->
。所以这个:
(struct date_t*)(one)->time
与此相同:
(struct date_t*)((one)->time)
你需要用括号括起来,然后你可以取消引用指针。
int cmpfunc (const void * one, const void * two) {
return ((const struct date_t*)(one))->time - ((const struct date_t*)two)->time;
}
另请注意,转换指针const
与原始指针一致。
答案 1 :(得分:1)
根据handy precedence table,强制转换操作的优先级低于结构成员访问操作符->
。因此,在执行(struct date_t*)(one)->time
时,首先访问成员time
(并且失败,因为one
是void*
并且没有这样的成员)。然后才对结果执行演员表。相反,您应该在适当的位置使用括号来强制优先级,例如:
... ((struct date_t*)one)->time ...