【问题标题】:casting a pointer to struct for qsort's compare为 qsort 的比较转换一个指向 struct 的指针
【发布时间】:2017-12-05 14:42:25
【问题描述】:

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

标签: c pointers casting qsort


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2019-01-18
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多