2010-04-01 2 views
4

я написал функцию сравненияПредупреждение при использовании QSort в C

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

и у меня есть мое заявление

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

и я звоню QSort в моей программе, как так

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

когда я скомпилирую его, я получаю следующее предупреждение

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 *)’ 

Программа работает очень хорошо, поэтому моя единственная проблема заключается в том, почему ей не нравится, как это использовать?

+0

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

+2

Просто предложение для более простой реализации вашего cmp; а не if if else, вы могли бы просто использовать вычитание. – nategoose

+0

@nategoose: Нет, если вы не хотите вводить неприятные ошибки переполнения целого числа. –

ответ

19

Прототип cmp функции должен быть

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

Вы можете бросить его в вызове QSort (не рекомендуется):

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

или бросает Пустоты указатели на INT-указатели в cmp (стандартный подход):

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

Технически первое - это неопределенное поведение. Нет никакой гарантии, что вызывающая конвенция вашей реализации передает 'const int *' так же, как она передает 'const void *'. На практике я ожидаю, что все будет хорошо. Очевидно, что GCC ожидает этого, так как это только предупреждение. –

+2

Подход с броском совершенно неприемлем, даже если это может показаться «работающим». – AnT

+2

@AndreyT: Что еще вы предлагаете? Напишите свой собственный быстрый вид? (Обратите внимание, что это C, а не C++, вы не можете использовать 'std :: sort'.) – kennytm

0

Согласно странице руководства, __compar_fn_t определяется как: typedef int(*) __compar_fn_t (const void *, const void *)

Ваш cmp указывает параметры int*. Это не нравится, но отображается только как предупреждение.

+0

Thats, потому что void * может быть неявно передан любому указателю другого типа. в C, по крайней мере, у C++ есть некоторые проблемы с ним. – Aatch

+0

На какой странице руководства вы смотрите? В одном для 'qsort' не упоминается' __compar_fn_t' – Flimm