指针转换为与qsort一起使用

时间:2012-04-28 13:55:20

标签: c pointers casting

这段代码从我正在阅读的书中复制:

/* 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

1 个答案:

答案 0 :(得分:7)

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

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

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

(尽管从const-correctness的观点来看,转换为const char **)会更正确