简体   繁体   English

指针转换为与qsort一起使用

[英]Pointer cast for use with qsort

This code snippet hand copied from a book I am reading: 从我正在阅读的书中复制的代码片段手:

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

This function is used with qsort to sort an array of strings. 此函数与qsort一起使用以对字符串数组进行排序。 The point I don't understand is, why v1 = *(char **) p1; 我不明白的一点是,为什么v1 = *(char **) p1; instead of just v1 = (char *) p1; 而不仅仅是v1 = (char *) p1; or wouldn't even this work; 或者甚至不会这样做; v1 = p1; ? I guess compiler should automatically typecast that assigment. 我想编译器应该自动对该分配进行类型转换。 Or even, consider this: 或者甚至,考虑一下:

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

I think (I might be awfully wrong) compiler is supposed to typecast p1 and p2 into char * since it's what strcmp(char *, char *) expects. 我认为(我可能非常错误)编译器应该将p1p2强制转换为char *因为它是strcmp(char *, char *)期望的。

To sum up, the question is why v1 = *(char **) p1 ? 总而言之,问题是为什么v1 = *(char **) p1

qsort passes to the comparing function a pointer to the elements it has to compare; qsort将指向它必须比较的元素的指针传递给比较函数; since in C there are no templates, this pointer is just brutally cast to a const void * ( void * in C just means "this is some kind of pointer", and to do something on it you must cast it back to its actual type). 因为在C中没有模板,这个指针只是残酷地转换为const void * (C中的void *只意味着“这是某种指针”,并且要对它做一些事情,你必须将它转换回它的实际类型)。

Now, if you are sorting an array of strings, each element you have to compare is a char * ; 现在,如果要对字符串数组进行排序,则必须比较的每个元素都是char * ; but qsort passes to the comparison function a pointer to each element, so what your scmp receives is actually a char ** (a pointer to a pointer to the first character of the string), casted to a const void * because the signature of the comparison function says so. qsort传递给比较函数一个指向每个元素的指针 ,所以你的scmp接收的实际上是一个char ** (一个指向字符串第一个字符的指针),被转换为一个const void *因为它的签名比较函数如此说。

So, to get your char * , you have first to convert the parameters to their actual type ( char ** ), and then dereference this pointer to get the actual char * you want to compare. 因此,要获取char * ,首先要将参数转换为实际类型( char ** ),然后取消引用此指针以获取要比较的实际char *

(although, it would be more correct from a const-correctness point of view to cast to const char ** ) (尽管从const-correctness的角度来看,转换为const char **会更正确)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM