qsort не работает для двойного массива

Я пытаюсь отсортировать массив двойных значений с помощью qsort, но, похоже, это не работает. Интересно, что здесь пошло не так??

#include <stdio.h>
#include <stdlib.h>
static double compare (const void * a, const void * b)
{
  if (*(double*)a > *(double*)b) return 1;
  else if (*(double*)a < *(double*)b) return -1;
  else return 0;  
}

int main() {

    int idx;
    double* sum_least_square_err;

    sum_least_square_err = (double*) malloc (2500*2500*sizeof(double));

    sum_least_square_err[0] = 0.642;    
    sum_least_square_err[1] = 0.236;
    sum_least_square_err[2] = 0.946;
    idx = 3;

    qsort(sum_least_square_err, idx, sizeof(sum_least_square_err), compare);

    int i;
    for (i=0; i<idx; i++){
       fprintf(stderr,"sum_least_square_err[%d] = %.3f\n", i, sum_least_square_err[i]);            
    }
    fprintf(stderr,"MAEE = %.3f\n", sum_least_square_err[idx/2]);

    free(sum_least_square_err);
}

Результат:

sum_least_square_err[0] = 0,642

sum_least_square_err[1] = 0,236

sum_least_square_err[2] = 0,946

МАЭЭ = 0,236


person twfx    schedule 13.08.2012    source источник
comment
При работе с qsort вы должны указать тип указателя функции: typedef int (*qsort_func_t)(const void *, const void *);. А затем в main(), qsort_func_t qsort_func = compare;, где qsort_func — параметр, передаваемый в qsort(). Если бы вы сделали это, вы бы получили ошибки/предупреждения компилятора, указывающие на ошибку.   -  person Lundin    schedule 13.08.2012


Ответы (2)


Изменять:

static double compare (const void * a, const void * b)

to:

static int compare (const void * a, const void * b)

и изменить:

qsort(sum_least_square_err, idx, sizeof(sum_least_square_err), compare);

to:

qsort(sum_least_square_err, idx, sizeof(sum_least_square_err[0]), compare);

Примечание: вы должны были получить соответствующее предупреждение компилятора о первой ошибке - вы компилируете с gcc -Wall или эквивалентным, и если да, то обращаете ли вы внимание на предупреждения компилятора? (Если нет, то, пожалуйста, примите подсказку и позвольте компилятору выявлять такие проблемы для вас в будущем.)

person Paul R    schedule 13.08.2012

Я считаю, что ваша ошибка в строке:

qsort(sum_least_square_err, idx, sizeof(sum_least_square_err), compare);

Проблема в том, что 3-й параметр должен быть sizeof(double), то есть размер элемента массива. Вместо этого вы передавали размер указателя, который может отличаться (и обычно бывает) от размера элемента.

Для получения дополнительной информации см.: http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/

Изменить: И Paul R прав в своем ответ: прототип вашей функции сравнения неверен. Прототип должен быть:

int ( * comparator ) ( const void *, const void * )

И последнее, но не менее важное: в вашем коде:

if (*(double*)a > *(double*)b) return 1;
else if (*(double*)a < *(double*)b) return -1;

Вы отбрасываете const. Здесь это не имеет последствий, но все же это дурной тон.

person paercebal    schedule 13.08.2012