#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. Спасибо, что это работает! Не могли бы вы, пожалуйста, прочитать мою правку тоже?