5

这个代码片段是从我正在阅读的一本书中手工复制的:

/* 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);
}

我认为(我可能大错特错)编译器应该进行类型转换,p1因为它是预期的。p2char *strcmp(char *, char *)

总而言之,问题是为什么v1 = *(char **) p1

4

1 回答 1

7

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

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

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

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

于 2012-04-28T13:59:39.097 回答