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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

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

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 — Примеч. автора.

scandir
читает каталог, имя которого дано в
dir
, создает с использованием
malloc
массив указателей
struct dirent
и устанавливает
*namelist
, чтобы он указывал на начало этого массива. Как массив указателей, так и указываемые структуры
struct dirent
выделяются с помощью
malloc
; вызывающий код должен использовать
free
, чтобы избежать утечек памяти.

Для выбора нужных элементов используйте указатель функции

select
. Когда это значение равно
NULL
, все действительные элементы каталога включаются в конечный массив. В противном случае
(*select)
вызывается для каждого элемента, и те элементы, для которых она возвращает ненулевое (истинное) значение, включаются в массив.

Указатель функции compare сравнивает два элемента каталога. Он передается функции

qsort
для использования при сортировке.

alphasort
лексикографически сравнивает имена файлов. Она использует для сравнения функцию
strcoll
.
strcoll
похожа на
strcmp
, но учитывает связанные с местной спецификой правила сортировки (см. раздел 13.4 «Не могли бы вы написать это для меня по буквам?»).

versionsort
является расширением GNU, которое использует для сравнения имен файлов функцию GNU
strverscmp
(см. strverscmp(3).) Короче говоря, эта функция понимает обычные соглашения по версиям имен файлов и сравнивает их соответствующим образом.

В

ch06-sortdir.c
приведена программа, похожая на
ch04-catdir.c
. Однако, она использует для работы
scandir
и
alphasort
.

1 /* ch06-sortdir.c --- Демонстрирует scandir, alphasort. */

2

3 #include <stdio.h> /* для printf etc. */

4 #include <errno.h> /* для errno */

5 #include <sys/types.h> /* для системных типов */

6 #include <dirent.h> /* для функций каталогов */

7

8 char *myname;

9 int process(const char *dir);

10

11 /* main --- перечислить аргументы каталога */

12

13 int main(int argc, char **argv)

14 {

15 int i;

16 int errs = 0;

17

18 myname = argv[0];

19

20 if (argc == 1)

21 errs = process("."); /* по умолчанию текущий каталог */

22 else

23 for (i = 1; i < argc; i++)

24 errs += process(argv[i]);

25

26 return (errs != 0);

27 }

28

29 /* nodots --- игнорирует файлы с точкой, для scandir */

30

31 int

32 nodots(const struct dirent *dp)

33 {

34 return (dp->d_name[0] != '.');

35 }

36

37 /*

38 * process --- сделать что-то с каталогом, в данном случае,

39 * вывести в стандартный вывод пары индекс/имя.

40 * Вернуть 0, если все нормально, в противном случае 1.

41 */

42

43 int

44 process(const char *dir)

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

Вперед в прошлое 7

Ратманов Денис
7. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 7

Вперед в прошлое 3

Ратманов Денис
3. Вперёд в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 3

Эволюционер из трущоб. Том 5

Панарин Антон
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 5

Сын счастья

Вассму Хербьёрг
2. Книга Дины
Проза:
современная проза
5.00
рейтинг книги
Сын счастья

Эволюционер из трущоб. Том 2

Панарин Антон
2. Эволюционер из трущоб
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Эволюционер из трущоб. Том 2

Проданная Истинная. Месть по-драконьи

Белова Екатерина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Проданная Истинная. Месть по-драконьи

Неучтенный элемент. Том 3

NikL
3. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 3

Кодекс Крови. Книга VIII

Борзых М.
8. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VIII

Газлайтер. Том 38

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

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Лекарь Империи

Карелин Сергей Витальевич
1. Лекарь Империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
попаданцы
5.00
рейтинг книги
Лекарь Империи

Несгибаемый граф. Тетралогия

Яманов Александр
Нет пророка в своем отечестве
Фантастика:
альтернативная история
фэнтези
5.00
рейтинг книги
Несгибаемый граф. Тетралогия

Некромант на страже человечества. Том 5

Клеванский Никита
5. Некромант на страже человечества
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Некромант на страже человечества. Том 5

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

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