массив структур qsort удаляет все

Поэтому у меня возникают проблемы с использованием qsort для сортировки массива структур.

В качестве примера я использовал эту ссылку: http://support.microsoft.com/kb/73853

Когда я запускаю программу, она дает мне пробелы для имен, которые изначально были в структуре, и нули для всех значений gp.

typedef int (*compfn)(const void*, const void*);

struct record
{
    char player[20];
    int gp;
};
struct record entries[15];

int compare(struct record *, struct record *);


void show ()           
{
    int v;
    qsort((void *)entries, 10, sizeof(struct record), (compfunc)compare);
    struct record *p = entries;
    for(v=0;v<counter;v++, p++)
    {
         printf("%s ..... %d \n", p->player , p->gp);
    }
}

int compare(struct record * p1, struct record * p2)
{
     if( p1->gp < p2->gp)
         return -1;
     else if (p1->gp > p2->gp)
         return 1;
     else
         return 0;
}

Редактировать: Привет всем, большое спасибо за вашу помощь, но я пробовал все, что вы, ребята, сказали, и это все равно просто сводит все значение к нулю.


person user2322610    schedule 26.04.2013    source источник
comment
это не должно компилироваться.   -  person Andreas Grapentin    schedule 26.04.2013
comment
Помимо (compfunc) до (compfn), у меня это работает   -  person 999k    schedule 26.04.2013


Ответы (2)


Ваш вызов можно упростить, не нужно приводить к void *:

qsort(entries, 10, sizeof entries[0], compare);

Обратите внимание на использование sizeof entries[0], чтобы избежать бессмысленного повторения типа массива.

Также не должно быть приведения функции сравнения, так как она должна быть просто определена в соответствии с прототипом:

static int compare(const void *a, const void *b)
{
  const struct record *ra = a, *rb = b;

  if( ra->gp < rb->gp)
     return -1;
  if (ra->gp > rb->gp)
     return 1;
  return 0;
}

Кстати, просто для информации, вот классический (?) способ стерифицировать трехстороннее тестирование, которое вы иногда видите в таких местах:

return (ra->gp < rb->gp) ? -1 : (ra->gp > rb->gp);

Я не спорю в пользу такого способа выражения, особенно если вы новичок, но подумал, что включу его, поскольку он актуален и может быть полезен для ознакомления.

person unwind    schedule 26.04.2013
comment
Классический способ, который я видел, это return (ra->gp > rb->gp) - (ra->gp < rb->gp); - person caf; 26.04.2013
comment
Классический способ, который я видел, - это return (ra->gp - rb->gp), но я не знаю, требует ли qsort Windows, чтобы результаты функции сравнения были в {-1, 0, 1}, а qsort linux - нет. - person Andreas Grapentin; 01.05.2013

Помимо того факта, что страницы поддержки Microsoft представляют собой настоящий беспорядок и не являются хорошим источником для изучения C, в вашем коде отсутствует & здесь:

...
qsort((void *)entries, 10, sizeof(struct record), (compfunc)compare);
... 

должно быть

...
qsort((void *)&entries, 10, sizeof(struct record), (compfunc)compare);
... 

также, я думаю, вы хотели написать

...
qsort((void *)&entries, 15, sizeof(struct record), (compfn)compare);
... 
person Andreas Grapentin    schedule 26.04.2013
comment
Имена массивов неявно преобразуются в указатели при использовании в выражении. - person luser droog; 26.04.2013
comment
@luserdroog Я знаю. Я просто хотел как можно ближе придерживаться кода, предоставленного на странице поддержки Microsoft, и OP. - person Andreas Grapentin; 26.04.2013
comment
Ага, понятно. Я не удосужился просмотреть эту страницу. Интересно, почему не написали (void *)(struct record *)&entries[0]: гораздо понятнее. :) - person luser droog; 26.04.2013
comment
Да, единственная причина, по которой я даже использовал страницу Microsoft, заключается в том, что на похожий вопрос о stackoverflow кто-то разместил эту ссылку и сказал, что это хороший пример, ха-ха - person user2322610; 26.04.2013
comment
@user2322610 user2322610 о, в таком случае посмотрите ответ unwind или справочную страницу qsort (linux.die.net /man/3/qsort) - person Andreas Grapentin; 27.04.2013