【问题标题】:Pointer cast for use with qsort用于 qsort 的指针转换
【发布时间】:2012-04-28 13:55:20
【问题描述】:

这段代码sn-p手抄自我正在读的一本书:

/* scmp: string compare of *p1 and *p2 */
int scmp(const void *p1, const void *p2)
{
        char *v1, *v2;
        v1 = *(char **) p1; 
        v2 = *(char **) p2; 

        return strcmp(v1, v2);
}

此函数与 qsort 一起用于对字符串数组进行排序。我不明白的一点是,为什么v1 = *(char **) p1; 而不仅仅是v1 = (char *) p1; 或者甚至不会这样工作; v1 = p1;?我猜编译器应该自动对该分配进行类型转换。甚至,考虑一下:

/* scmp: string compare of *p1 and *p2 */
int scmp(const void *p1, const void *p2)
{
        return strcmp(p1, p2);
}

我认为(我可能大错特错)编译器应该将 p1p2 类型转换为 char *,因为这是 strcmp(char *, char *) 所期望的。

总结一下,问题是为什么v1 = *(char **) p1

【问题讨论】:

    标签: c pointers casting


    【解决方案1】:

    qsort 向比较函数传递一个指向它必须比较的元素的指针;因为在 C 中没有模板,所以这个指针只是被粗暴地转换为 const void *(C 中的void * 只是意味着“这是某种指针”,并且要对它做一些事情,你必须将它转换回它的实际值类型)。

    现在,如果要对字符串数组进行排序,则必须比较的每个元素都是 char *;但是qsort 将一个 pointer 传递给比较函数到每个元素,所以你的scmp 收到的实际上是一个char **(一个指向字符串第一个字符的指针的指针),强制转换为 const void *,因为比较函数的签名是这样写的。

    因此,要获取您的char *,您必须首先将参数转换为其实际类型(char **),然后取消引用此指针以获取您要比较的实际char *

    (尽管从 const 正确性的角度来看,转换为 const char ** 会更正确)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 2013-10-09
      • 2019-01-18
      • 2021-07-29
      • 1970-01-01
      相关资源
      最近更新 更多