2010-11-09 3 views
4

La page de manuel de la routine de bibliothèque qsort(3) donne un exemple de tri des mots donnés comme arguments sur la ligne de commande. La fonction de comparaison se lit comme suit:La page de manuel de qsort (3) est-elle exacte?

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

Mais ce qui est trié ici sont les éléments de argv. Maintenant argv est un pointeur vers des pointeurs de chars, qui peuvent être vus aussi comme une table de pointeurs aux chars. Par conséquent, ses éléments sont des pointeurs vers des caractères, donc les arguments réels de cmpstringp ne devraient-ils pas être des pointeurs vers des caractères, et non des "pointeurs vers des pointeurs sur char"?

+1

Si vous étiez en train de trier un tableau d'ints, auriez-vous alors prévu de transformer le 'const void * p1' en un' int' plutôt qu'un 'const int *'? Qu'en est-il d'un tableau de structures de 10 Ko, où les éléments sont beaucoup plus grands que le vide * pourrait être? –

+0

Tout en travaillant à partir de ce code pour comprendre ce qui se passe est parfaitement raisonnable, vous voudrez peut-être reconsidérer le titre de votre question. Je veux dire, est-ce que vous vous rendez compte combien de temps cette manpage et ce code ont existé? Combien de * globes oculaires les ont-ils pris? – dmckee

Répondre

7

La fonction de rappel transmise en tant qu'argument à qsort() est appelée avec comme arguments des pointeurs vers les deux valeurs à comparer. Si vous triez un tableau de char * (par exemple argv[]) alors les valeurs sont char * (pointeurs vers char) et la fonction de comparaison recevra des pointeurs vers de telles valeurs, c'est-à-dire des pointeurs vers des pointeurs vers char.

0

Non, parce que sans doute vous appelleriez qsort comme suit:

qsort(&argv[0], argc, sizeof(char*), cmpstringp); 

dire que vous passez un pointeur à l'élément, et un élément est un const char *.

2
 
strcmp(* (char * const *) p1, * (char * const *) p2) 
     ^^^^^^^^^^^^^^^^^^^^^ 

Alors p1 est de type * (char * const *) ou, en supprimant * 's (char * const); et char *const est assignation compatible avec char *, donc pas de problème :-)

Questions connexes