为 qsort 的比较投射一个指向结构的指针

casting a pointer to struct for qsort's compare

所以我在 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;
}

但是,我该如何使用演员表呢?

类型转换运算符 () 的优先级低于成员指针运算符 ->。所以这个:

(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 与原始指针保持一致。

根据handy precedence table,强制转换操作的优先级低于结构成员访问操作符->。因此,当执行 (struct date_t*)(one)->time 时,首先访问成员 time(并且失败,因为 one 是一个 void* 并且没有这样的成员)。然后才对结果执行强制转换。相反,您应该通过在适当的地方使用括号来强制优先,例如:

... ((struct date_t*)one)->time ...