Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Если компилятор поддерживает арифметику комплексных чисел, то в нем доступен файл complex.h, в котором объявлены комплексные аналоги математических функций. Например, в этом файле объявлены функции csqrtf(), csqrt() и csqrtl(), которые возвращают комплексный квадратный корень типа float complex, double complex и long double complex, соответственно. Когда такая поддержка предоставляется, макрос sqrt() из tgmath.h также может разворачиваться в связанную функцию комплексного квадратного корня.
Если вы хотите, скажем, вызвать функцию sqrt() вместо макроса sqrt() , даже несмотря на то, что файл tgmath.h включен, можете поместить имя функции в круглые скобки:
#include
float х = 44.0; double у;
у = sqrt(x); // вызов макроса, следовательно sqrtf(х)
у= (sqrt) (х); // вызов функции sqrt()
Код работает, поскольку имя функционального макроса должно сопровождаться последующей открывающей круглой скобкой, что обходится путем заключения имени в пару скобок. В противном случае круглые скобки не оказывают воздействия на выражение, находящееся внутри них, кроме изменения порядка следования операций, поэтому помещение в скобки имени функции по-прежнему в результате приводит к ее вызову. На самом деле, из-за странно противоречивых правил, принятых в С относительно указателей на функции, для вызова функции sqrt() можно также использовать (* sqrt)().
698 Глава 16
Средство выражений _Generic, добавленное в стандарт С11, является простым способом реализации макросов tgmath.h, не прибегая к механизмам, которые выходят за рамки стандарта С.
Библиотека утилит общего назначения
Библиотека утилит общего назначения содержит множество функций, включая генератор случайных чисел, функции для поиска и сортировки, функции для преобразования и функции для управления памятью. Вы уже видели работу функций rand(), srand(), malloc() и free() в главе 12. В ANSI С прототипы этих функций находятся в заголовочном файле stdlib.h. В разделе V приложения Б перечислены все функции в этом семействе; далее мы рассмотрим некоторые из них более подробно.
ФУНКЦИИ exit() и atexit()
Функция exit() уже применялась явно в нескольких примерах. Вдобавок функция exit() вызывается автоматически при возвращении из main(). В стандарт ANSI добавлена пара интересных возможностей, которые мы еще не использовали. Самая важная из них — возможность указания определенных функций, которые должны вызываться во время выполнения exit(). Функция atexit() обеспечивает это за счет регистрации функций, предназначенных для вызова при выполнении exit(). Функция atexit() принимает в качестве аргумента указатель на функцию.
В листинге 16.16 показано, как это работает.
Листинг 16.16. Программа byebye.c
Препроцессор и библиотека С 699
Ниже показаны результаты пробного запуска:
Введите целое число:
212
212 является четным.
Завершение работы очередной замечательной программы от SeeSaw Software!
Если программа выполняется в IDE-среде, две последних строки вы можете не увидеть.
Рассмотрим результаты второго пробного запуска:
Введите целое число: что?
Это не целое число!
SeeSaw Software приносит искренние соболезнования в связи с отказом программы.
Завершение работы очередной замечательной программы от SeeSaw Software!
Если программа выполняется в IDE-среде, четыре последних строки вы можете не увидеть.
Давайте посмотрим на две основных области: применение функции atexit() и аргументы exit().
Использование функции atexit()
Все-таки есть функция, которая принимает указатели на функции! Чтобы использовать ее, просто передайте адрес функции, которая должна быть вызвана при выходе. Поскольку имя функции действует как адрес, когда применяется в качестве аргумента функции, для аргумента можно указывать имя sign of f или too bad. Затем atexit() регистрирует эту функцию в списке функций, предназначенных для выполнения при вызове exit(). Стандарт ANSI гарантирует, что список может вмещать не менее 32 функций. Каждая из них добавляется с помощью отдельного вызова atexit(). Когда функция exit(), в конце концов, вызывается, она выполняет эти функции, причем первой выполняется функция, добавленная в список последней.
Обратите внимание, что в результате недопустимого ввода пользователя вызываются обе функции, sign_of f() и too bad(), но в случае ввода допустимого значения вызывается только sign of f(). Дело в том, что оператор if регистрирует функцию too bad() только для случая недопустимого ввода. Кроме того, первой была вызвана функция, зарегистрированная последней.
Функции, регистрируемые atexit(), вроде sign_off() и too bad(), должны иметь тип void и не принимать аргументов. Обычно они решают вспомогательные задачи, такие как обновление файла мониторинга программы или переустановка переменных среды.
Обратите внимание, что sign off() вызывается даже в случае, когда функция exit() не вызывается явно; причина в том, что exit() неявно вызывается при заверь щении main().
Использование функции exit()
Когда exit() выполняет функции, указанные с помощью atexit(), она предпринимает собственные шаги по очистке. Функция exit() сбрасывает все потоки вывода, закрывает все открытые потоки и закрывает временные файлы, созданные в результате обращений к стандартной функции ввода-вывода tmpfile(). Затем exit() возвращает управление размещаемой среде и по возможности сообщает среде состояние
700 глава 16 завершения. Традиционно программы для Unix применяли 0, чтобы указать на успешное завершение, и ненулевое значение для сообщения об отказе. Коды возврата Unix не обязательно работают со всеми системами, поэтому в ANSI С определен макрос по имени EXIT FAILURE, который может использоваться переносимым образом для обозначения отказа. Аналогично, в ANSI С определен макрос EXIT_SUCCESS для указания на успешное завершение, но exit() также принимает для этой цели значение 0. В рамках стандарта ANSI С применение exit() в нерекурсивной функции main() эквивалентно использованию ключевого слова return. Тем не менее, exit() также завершает программу, когда применяется в функциях, отличных от main().
Функция qsort()
Метод быстрой сортировки входит в число наиболее эффективных алгоритмов сортировки, особенно в случае крупных массивов. Разработанный Чарльзом Энтони Ричардом Хоаром в 1962 году, этот алгоритм разделяет массивы на постоянно уменьшающиеся части, пока не будет достигнут уровень элемента. Сначала массив делится на две части, так что любое значение в одной части меньше любого значения в другой части. Этот процесс продолжается вплоть до момента, когда массив станет полностью отсортированным.
Алгоритм быстрой сортировки реализован в С под именем qsort(). Эта функция сортирует массив объектов данных. Она имеет следующий прототип ANSI:
void qsort (void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
Читать дальшеИнтервал:
Закладка: