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

#c #struct #qsort

#c #struct #qsort

Вопрос:

Я создаю функцию сравнения для использования 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);
  

Комментарии:

1. Что это за тип ARRAY ? Является ли этот массив struct ?

2. Да, именно так это определено: stringa **newarray = NULL; newarray = malloc ( n * sizeof (struct _stringa *) );

3. Измените sizeof(struct _stringa) на sizeof(struct _stringa *) .

4. Спасибо, теперь это работает. Просто нужно исправить другие ошибки, потому что сортировка ведет себя странно

Ответ №1:

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

 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;
}
  

Ответ №2:

Вам нужен еще один уровень заключения в круглые скобки

 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);
  

Комментарии:

1. Спасибо, что это работает! Не могли бы вы, пожалуйста, прочитать мою правку тоже?