2010-04-01 6 views
4

j'ai écrit ma fonction de comparaisonAvertissement lors de l'utilisation qsort en C

int cmp(const int * a,const int * b) 
{ 
    if (*a==*b) 
    return 0; 
else 
    if (*a < *b) 
    return -1; 
else 
    return 1; 
} 

et j'ai ma déclaration

int cmp (const int * value1,const int * value2); 

et j'appelle qsort dans mon programme comme si

qsort(currentCases,round,sizeof(int),cmp); 

quand je le compile je reçois l'avertissement suivant

warning: passing argument 4 of ‘qsort’ from incompatible pointer type 
/usr/include/stdlib.h:710: note: expected ‘__compar_fn_t’ but argument is of type ‘int 
(*)(const int *, const int *)’ 

Le programme fonctionne très bien, donc mon seul souci est de savoir pourquoi il n'aime pas l'utilisation im cela?

+0

http://stackoverflow.com/questions/2228695/what-are-the-parameters-in-this-c-qsort-function-call/2228754#2228754 –

+2

Juste une suggestion pour une implémentation plus simple de votre cmp; plutôt que les trucs if/else, vous pouvez simplement utiliser la soustraction. – nategoose

+0

@nategoose: Non, sauf si vous voulez introduire des bogues débordants d'entiers. –

Répondre

19

Le prototype de la fonction cmp doit être

int cmp(const void* a, const void* b); 

Vous pouvez le jeter dans l'invocation de qsort (non recommandé):

qsort(currentCases, round, sizeof(int), (int(*)(const void*,const void*))cmp); 

ou jette les pointeurs vides-int-pointeurs cmp (l'approche standard):

int cmp(const void* pa, const void* pb) { 
    int a = *(const int*)pa; 
    int b = *(const int*)pb; 
    ... 
+6

Techniquement, le premier est un comportement indéfini. Il n'y a aucune garantie que la convention d'appel de votre implémentation passe un 'const int *' de la même façon qu'elle passe un 'const void *'. En pratique, je m'attends à ce que ça se passe bien. Apparemment, GCC s'attend à cela aussi, car c'est seulement un avertissement. –

+2

L'approche avec le casting est complètement inacceptable, même si cela peut sembler "fonctionner". – AnT

+2

@AndreyT: Quoi d'autre suggérez-vous? Écrivez votre propre tri rapide? (Notez que ceci est C, pas C++, vous ne pouvez pas utiliser 'std :: sort'.) – kennytm

0

Selon la page de manuel, un __compar_fn_t est défini comme: typedef int(*) __compar_fn_t (const void *, const void *)

Votre cmp spécifie les paramètres int*. Il n'aime pas ça, mais est seulement listé comme un avertissement.

+0

C'est parce que void * peut être implicitement cast à tout autre type de pointeur. en C au moins, C++ a quelques problèmes avec cela. – Aatch

+0

Quelle page de manuel regardez-vous? Celui pour 'qsort' ne mentionne pas' __compar_fn_t' – Flimm

Questions connexes