Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

c - 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. The point I don't understand is, why v1 = *(char **) p1; instead of just 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.

To sum up, the question is why v1 = *(char **) p1 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

qsort passes to the comparing function a pointer to the elements it has to compare; 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).

Now, if you are sorting an array of strings, each element you have to compare is a 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.

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.

(although, it would be more correct from a const-correctness point of view to cast to const char **)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...