Язык программирования Си - [50]
>#include ‹stdio.h›
>#include ‹string.h›
>#define MAXLINES 5000 /* максимальное число строк */
>char *lineptr[MAXLINES]; /* указатели на строки текста */
>int readlines(char *lineptr[], int nlines);
>void writelines(char *lineptr[], int nlines);
>void qsort(void *lineptr[], int left, int right,
>int (*comp)(void *, void *));
>int numcmp(char *, char *);
>/* сортировка строк */
>main(int argc, char *argv[])
>{
> int nlines; /* количество прочитанных строк */
> int numeric = 0; /* 1, если сорт. по числ. знач. */
> if (argc › 1 && strcmp(argv[1], "-n") == 0)
> numeric = 1;
> if ((nlines = readlines(lineptr, MAXLINES)) ›= 0) {
> qsort((void **) lineptr, 0, nlines-1,
> (int (*)(void*,void*))(numeric ? numcmp : strcmp));
> writelines(lineptr, nlines);
> return 0;
> } else {
> printf("Bведено слишком много строк\n");
> return 1;
> }
>}
В обращениях к функциям qsort, strcmp и numcmp их имена трактуются как адреса этих функций, поэтому оператор& перед ними не нужен, как он не был нужен и перед именем массива.
Мы написали qsort так, чтобы она могла обрабатывать данные любого типа, а не только строки символов. Как видно из прототипа, функция qsort в качестве своих аргументов ожидает массив указателей, два целых значения и функцию с двумя аргументами-указателями. В качестве аргументов-указателей заданы указатели обобщенного типа void *. Любой указатель можно привести к типу void * и обратно без потери информации, поэтому мы можем обратиться к qsort, предварительно преобразовав аргументы в void *. Внутри функции сравнения ее аргументы будут приведены к нужному ей типу. На самом деле эти преобразования никакого влияния на представления аргументов не оказывают, они лишь обеспечивают согласованность типов для компилятора.
>/* qsort: сортирует v[left]…v[right] по возрастанию */
>void qsort(void *v[], int left, int right, int (*comp)(void *, void *))
>{
> int i, last;
> void swap(void *v[], int, int);
> if (left ›= right) /* ничего не делается, если */
> return; /* в массиве менее двух элементов */
> swap(v, left, (left + right)/2);
> last = left;
> for (i = left+1; i ‹= right; i++)
> if ((*comp)(v[i], v[left]) ‹ 0)
> swap(v, ++last, i);
> swap(v, left, last);
> qsort(v, left, last-1, comp);
> qsort(v, last+1, right, comp);
>}
Повнимательней приглядимся к объявлениям. Четвертый параметр функции qsort:
>int (*comp)(void *, void *)
сообщает, что comp - это указатель на функцию, которая имеет два аргумента- указателя и выдает результат типа int. Использование comp в строке
>if ((*comp)(v[i], v[left]) ‹ 0)
согласуется с объявлением "comp - это указатель на функцию", и, следовательно, *comp - это функция, а
>(*comp)(v[i], v[left])
- обращение к ней. Скобки здесь нужны, чтобы обеспечить правильную трактовку объявления; без них объявление
>int *comp(void *, void *) /* НЕВЕРНО */
говорило бы, что comp - это функция, возвращающая указатель на int, а это совсем не то, что требуется.
Мы уже рассматривали функцию strcmp, сравнивающую две строки. Ниже приведена функция numcmp, которая сравнивает две строки, рассматривая их как числа; предварительно они переводятся в числовые значения функцией atof.
>#include ‹stdlib.h›
>/* numcmp: сравнивает s1 и s2 как числа */
>int numcmp(char *s1, char *s2)
>{
> double v1, v2;
> v1 = atof(s1);
> v2 = atof(s2);
> if (v1 ‹ v2)
> return -1;
> else if (v1 › v2)
> return 1;
> else
> return 0;
>}
Функция swap, меняющая местами два указателя, идентична той, что мы привели ранее в этой главе за исключением того, что объявления указателей заменены на void*.
>void swap(void *v[], int i, int j)
>{
> void *temp;
> temp = v[i];
> v[i] = v[j];
> v[j] = temp;
>}
Программу сортировки можно дополнить и множеством других возможностей; реализовать некоторые из них предлагается в качестве упражнений.
Упражнение 5.14. Модифицируйте программу сортировки, чтобы она реагировала на параметр -r, указывающий, что объекты нужно сортировать в обратном порядке, т. е. в порядке убывания. Обеспечьте, чтобы -r работал и вместе с -n.
Упражнение 5.15. Введите в программу необязательный параметр -f, задание которого делало бы неразличимыми символы нижнего и верхнего регистров (например, a и A должны оказаться при сравнении равными).
Упражнение 5.16. Предусмотрите в программе необязательный параметр -d, который заставит программу при сравнении учитывать только буквы, цифры и пробелы. Организуйте программу таким образом, чтобы этот параметр мог работать вместе с параметром -f.
Упражнение 5.17. Реализуйте в программе возможность работы с полями: возможность сортировки по полям внутри строк. Для каждого поля предусмотрите свой набор параметров. Предметный указатель этой книги (Имеется в виду оригинал книги на английским языке. - Примеч. пер.) упорядочивался с параметрами: -df для терминов и -n для номеров страниц.
5.12 Сложные объявления
Иногда Си ругают за синтаксис объявлений, особенно тех, которые содержат в себе указатели на функции. Таким синтаксис получился в результате нашей попытки сделать похожими объявления объектов и их использование. В простых случаях этот синтаксис хорош, однако в сложных ситуациях он вызывает затруднения, поскольку объявления перенасыщены скобками и их невозможно читать слева направо. Проблему иллюстрирует различие следующих двух объявлений:

В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями shell.Для программистов-пользователей операционной системы UNIX.

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)

Что такое ГЕЙМДИЗАЙН? Это не код, графика или звук. Это не создание персонажей или раскрашивание игрового поля. Геймдизайн – это симулятор мечты, набор правил, благодаря которым игра оживает. Как создать игру, которую полюбят, от которой не смогут оторваться? Знаменитый геймдизайнер Тайнан Сильвестр на примере кейсов из самых популярных игр рассказывает как объединить эмоции и впечатления, игровую механику и мотивацию игроков. Познакомитесь с принципами дизайна, которыми пользуются ведущие студии мира! Создайте игровую механику, вызывающую эмоции и обеспечивающую разнообразие.

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

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

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

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.