Для более сложных структур требуются более сложные функции. Например, рассмотрите следующую (довольно тривиальную) struct employee
struct employee {
char lastname[30];
char firstname[30];
long emp_id;
time_t start_date;
};
Мы могли бы написать функцию для сортировки сотрудников по фамилии, имени и идентификационному номеру:
int emp_name_id_compare(const void *e1p, const void *e2p) {
const struct employee *e1, *e2;
int last, first;
e1 = (const struct employee*)e1p; /* Преобразовать указатели */
e2 = (const struct employee*)e2p;
if ((last = strcmp(e1->lastname, e2->lastname)) != 0)
/* Сравнить фамилии */
return last; /* Фамилии различаются */
/* фамилии совпадают, сравнить имена */
if ((first = strcmp(e1->firstname, e2->firstname)) != 0)
/* Сравнить имена */
return first; /* Имена различаются */
/* имена совпадают, сравнить номера ID */
if (e1->emp_id < e2->emp_id) /* Сравнить ID сотрудника */
return -1;
else if (e1->emp_id == e2->emp_id)
return 0;
else
return 1;
}
Логика здесь проста: сначала сравниваются фамилии, затем имена, а затем номера ID, если два имени совпадают. Используя для строк strcmp()
При сравнении ID сотрудников нельзя просто использовать вычитание: представьте, что long
int 32-разрядный, а два значения отличаются лишь в старших 32 битах (скажем, младшие 32 бита равны нулю). В таком случае вычитание автоматически привело бы к приведению типа к int с отбрасыванием старших 32 битов и возвращением неверного результата.ЗАМЕЧАНИЕ
. Возможно, мы остановились при сравнении имен, в этом случае все сотрудники с совпадающими фамилиями и именами оказались бы сгруппированы, но никак не отсортированыЭто важный момент qsort()
Просто используя другую функцию, мы можем отсортировать сотрудников по старшинству:
int emp_seniority_compare(const void *e1p,
const void *e2p) {
const struct employee *e1, *e2;
double diff;
/* Привести указатели к нужному типу */
e1 = (const struct employee*)e1p;
e2 = (const struct employee*)e2p;
/* Сравнить времена */
diff = difftime(e1->start_date, e2->start_date);
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
else
return 0;
}
Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT