指针转换为与qsort一起使用
从我正在阅读的书中复制的代码片段手:
/* 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
和p2
强制转换为char *
因为它是strcmp(char *, char *)
期望的。
总而言之,问题是为什么v1 = *(char **) p1
?
qsort
向比较函数传递一个指向它必须比较的元素的指针; 因为在C中没有模板,这个指针只是被粗暴地强制转换为const void *
(C中的void *
只意味着“这是某种指针”,并且要对它做一些事情,你必须将它强制转换为它的实际类型)。
现在,如果要对字符串数组进行排序,则必须比较的每个元素都是char *
; 但是qsort
向比较函数传递一个指向每个元素的指针 ,所以你的scmp
接收的实际上是一个char **
(一个指向字符串第一个字符的指针),被转换为一个const void *
因为它的签名比较function如此说明。
因此,要获取char *
,首先要将参数转换为实际类型( char **
),然后取消引用此指针以获取要比较的实际char *
。
(尽管从const-correctness的角度来看,转换为const char **
会更正确)