Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

82 qsort(presidents, npres, sizeof(struct employee), emp_name_id_compare);

83

84 /* Вывести результат */

85 printf("Sorted by name:\n");

86 for (i = 0; i < npres; i++)

87 printf("\t%s %s\t%d\t%s",

88 presidents[i].lastname,

89 presidents[i].firstname,

90 presidents[i].emp_id,

91 ctime(&presidents[i].start_date));

92

93 /* Теперь сортировка по старшинству */

94 qsort(presidents, npres, sizeof(struct employee), emp_seniority_compare);

95

96 /* И снова вывести */

97 printf("Sorted by seniority:\n");

98 for (i = 0; i < npres; i++)

99 printf("\t%s %s\t%d\t%s",

100 presidents[i].lastname,

101 presidents!i].firstname,

102 presidents[i].emp_id,

103 ctime(&presidents[i].start_date));

104 }

Строки 70–77 считывают данные. Обратите внимание, что любое использование

scanf
требует от входных данных «хорошего поведения». Если, например, какое-нибудь имя содержит более 29 символов, возникает проблема. В данном случае, мы вне опасности, но в коде изделия нужно быть гораздо более осмотрительным.

Строка 82 сортирует данные по имени и по ID сотрудника, а затем строки 84–91 выводят отсортированные данные. Сходным образом строка 94 пересортировывает данные, на этот раз по старшинству, а строки 97–103 выводят результаты. После компилирования и запуска программа выдает следующие результаты:

$ ch06-sortemp < presdata.txt

Sorted by name:

Bush George 41 Fri Jan 20 13:00:00 1989

Bush George 43 Sat Jan 20 13:00:00 2001

Carter James 39 Thu Jan 20 13:00:00 1977

Clinton William 42 Wed Jan 20 13:00:00 1993

Reagan Ronald 40 Tue Jan 20 13:00:00 1981 \

Sorted by seniority:

Carter James 39 Thu Jan 20 13:00:00 1977

Reagan Ronald 40 Tue Jan 20 13:00:00 1981

Bush George 41 Fri Jan 20 13:00:00 1989

Clinton William 42 Wed Jan 20 13:00:00 1993

Bush George 43 Sat Jan 20 13:00:00 2001

(Мы использовали 1 час пополудни как приблизительное время, когда все президенты начали работать.) [66]

Стоит заметить одну вещь:

qsort
переставляет данные в массиве. Если каждый элемент массива представляет собой большую структуру, при сортировке массива большое количество данных будут копироваться туда-сюда. Вместо этого может оказаться выгодным создать отдельный массив указателей, каждый из которых указывает на один элемент массива. Затем использовать
qsort
для сортировки массива указателей, получая доступ к несортированным данным через сортированные указатели.

66

Вывод, показанный здесь, относится к US Eastern Standard Time. Вы получите различные результаты для одних и тех же программ и данных, если используете другой часовой пояс — Примеч. автора.

Платой за это является дополнительная память для размещения указателей и модификация функций сравнения для дополнительного перенаправления указателей при сравнении структур. Полученной выгодой может стать значительное ускорение работы, поскольку на каждом шаге перемещается лишь четырех- или восьмибайтный указатель вместо большой структуры. (Наша

struct employee
имеет размер по крайней мере 68 байтов. При обмене четырехбайтных указателей перемещается в 17 раз меньше данных, чем при обмене структур.) Для тысяч размещенных в памяти структур разница мажет быть существенной.

ЗАМЕЧАНИЕ. Если вы являетесь программистом С++, знайте!

qsort
может быть опасной для использования с массивами объектов!
qsort
осуществляет простые перемещения памяти, копируя байты. Она совершенно ничего не знает о конструкциях С++, таких, как конструкторы копирования или функции
operator=
. Вместо этого используйте одну из функций сортировки STL [67] или используйте методику отдельного массива указателей.

67

STL (Standard Template Library, стандартная библиотека шаблонов). — Примеч. науч. ред.

6.2.1.2. Пример: сортировка содержимого каталога

В разделе 5.3 «Чтение каталогов» мы продемонстрировали, как элементы каталогов возвращаются в физическом порядке каталога. В большинстве случаев гораздо полезнее иметь содержимое каталога отсортированным каким-нибудь образом, например, по имени или по времени изменения. Хотя и не стандартизованные POSIX, несколько процедур упрощают это, используя

qsort
в качестве лежащего в основе сортирующего агента:

#include <dirent.h> /* Обычный */

int scandir(const char *dir, struct dirent ***namelist,

 int (*select)(const struct dirent*),

 int (*compare)(const struct dirent **, const struct dirent **));

int alphasort(const void *a, const void *b);

int versionsort(const void *a, const void *b); /* GLIBC */

Функции

scandir
и
alphasort
были сделаны доступными в 4.2 BSD и широко поддерживаются [68] ,
versionsort
является расширением GNU.

68

Заметным исключением является лишь Sun Solaris, где эти две функции существуют лишь в трудной для использования библиотеке совместимости с BSD — Примеч. автора.

Поделиться:
Популярные книги

Черный Маг Императора 12

Герда Александр
12. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 12

Император Пограничья 10

Астахов Евгений Евгеньевич
10. Император Пограничья
Фантастика:
городское фэнтези
аниме
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 10

Мастер...

Чащин Валерий
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Мастер...

Гранит науки. Том 2

Зот Бакалавр
2. Героями не становятся, ими умирают
Фантастика:
фэнтези
5.00
рейтинг книги
Гранит науки. Том 2

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение

Тактик

Земляной Андрей Борисович
2. Офицер
Фантастика:
альтернативная история
7.70
рейтинг книги
Тактик

Ст. сержант. Назад в СССР. Книга 5

Гаусс Максим
5. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ст. сержант. Назад в СССР. Книга 5

Рассвет русского царства. Книга 2

Грехов Тимофей
2. Новая Русь
Фантастика:
альтернативная история
попаданцы
историческое фэнтези
5.00
рейтинг книги
Рассвет русского царства. Книга 2

Надуй щеки! Том 2

Вишневский Сергей Викторович
2. Чеболь за партой
Фантастика:
попаданцы
дорама
фантастика: прочее
5.00
рейтинг книги
Надуй щеки! Том 2

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

Последний Паладин. Том 3

Саваровский Роман
3. Путь Паладина
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 3

Воин

Бубела Олег Николаевич
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Воин

Неправильный лекарь. Том 4

Измайлов Сергей
4. Неправильный лекарь
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Неправильный лекарь. Том 4

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI