Domanda

I have following question: My compare function in qsort looks like this:

static int compare(const void *arg1, const void *arg2) {
    return strcmp((const char *) arg1, (const char *) arg2);
}

This did not work, so I looked up the code example in the man page and I changed it a little bit, so now it looks like this:

static int compare(const void *arg1, const void *arg2) {
    return strcmp( *(char * const *) arg1, *(char * const *) arg2);
}

I don't get it why the method of the man page works, because the parameter of strcmp are const char *s1 and const char *s2.

I am pretty new to C, so I find it difficult to understand this. Can someone please explain this to me why only the method of the man pages works.

È stato utile?

Soluzione

The succinct answer to your question is that the pointers passed to the comparison function are not char * but char **.

If you think about it, if you were sorting an array of integers, you'd be passed two int * values (disguised as void *). If you are sorting an array of doubles, you'd be passed two double * values; if you are sorting an array of strings, you are passed two pointers to strings, which means two char ** values.

Altri suggerimenti

man qsort says:

The contents of the array are sorted in ascending order according to a comparison function pointed to by compar, which is called with two arguments that point to the objects being compared.

It's clear that "with two arguments that point to the objects being compare". So when comparing two char * strings, the argument are in type "pointers to pointers to char", which is also covered in the manpage:

   static int
   cmpstringp(const void *p1, const void *p2)
   {
       /* The actual arguments to this function are "pointers to
          pointers to char", but strcmp(3) arguments are "pointers
          to char", hence the following cast plus dereference */

       return strcmp(* (char * const *) p1, * (char * const *) p2);
   }

And man strcmp will tell you that its prototype is:

int strcmp(const char *s1, const char *s2);

where the arguments are "pointers to char".

Therefore the conversion solves this.

You may need to read the manpage carefully.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top