Как преобразовать функцию сравнения с typedef в c

Я создаю функцию сравнения для использования qsort (), но не могу правильно преобразовать элементы. Я пробовал с разными вещами, но ничего не получается. Может кто-нибудь объяснить мне правильную логику этого? Заранее спасибо!

typedef struct _stringa {
    char* string;
    int freq;
} stringa;


int compare(const void *elem1, const void *elem2) {

    if (*(stringa*)elem1.freq < *(stringa*)elem2.freq) {
        return -1;
    } else if (*(stringa*)elem1.freq > *(stringa*)elem2.freq) {
        return 1;
    }

    return 0;
}

РЕДАКТИРОВАТЬ: Извините за второй вопрос, но моя сортировка не работает и, кажется, «удаляет» элементы. Это правильный способ вызвать qsort?

qsort(ARRAY, ARRAY_DIMENSION, sizeof(struct _stringa), compare);

person Roberto    schedule 05.07.2014    source источник
comment
Какой тип ARRAY? Это массив struct?   -  person haccks    schedule 05.07.2014
comment
Да, вот как это определяется: stringa ** newarray = NULL; newarray = malloc (n * sizeof (struct _stringa *));   -  person Roberto    schedule 05.07.2014
comment
Измените sizeof(struct _stringa) на sizeof(struct _stringa *).   -  person haccks    schedule 05.07.2014
comment
Спасибо, теперь работает. Просто нужно исправить другие ошибки, потому что sort ведет себя странно   -  person Roberto    schedule 05.07.2014


Ответы (2)


Похоже, вас застала проблема с порядком работы. Чтобы предотвратить это и сделать код более читабельным, вы можете выполнить приведение за одну операцию, а затем сравнить:

int compare(const void *elem1, const void *elem2) {
    stringa *first = (stringa *)elem1;
    stringa *second = (stringa *)elem2;

    if (first->freq < second->freq) {
        return -1;
    } else if (first->freq > second->freq) {
        return 1;
    }

    return 0;
}
person Platinum Azure    schedule 05.07.2014

Вам нужен еще один уровень скобок

int compare(const void *elem1, const void *elem2) {

    if ( (*(stringa*)elem1 ).freq < ( *(stringa*)elem2 ).freq) ) {
        return -1;
    } else if ( (*(stringa*)elem1 ).freq > ( *(stringa*)elem2 ).freq) ) {
        return 1;
    }

    return 0;
}

Без (*(stringa*)elem1 ) компилятор преобразует elem1.freq в stringa*, а затем попытается разыменовать elem1.freq.

РЕДАКТИРОВАТЬ: Поскольку вы объявили ARRAY как указатель на указатель на _stringa, вам необходимо передать размер указателя на _stringa в qsort в качестве аргумента thirs:

qsort(ARRAY, ARRAY_DIMENSION, sizeof(struct _stringa *), compare);
person haccks    schedule 05.07.2014
comment
Спасибо, хаки, все работает! Не могли бы вы также прочитать мою правку? - person Roberto; 05.07.2014