
Препроцессор и библиотека С 711

Ниже показаны результаты пробного запуска:
возвращаемое значение sum(3, 1.1, 2.5, 13.3): 16.9
возвращаемое значение sum (6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1): 31.6
Проверив вычисления, вы обнаружите, что функция sum() сложила три числа при первом вызове и шесть чисел — при втором.
В общем случае, функции с переменным числом аргументов сложнее в использовании по сравнению с макросами такого рода, но имеют более широкий диапазон применений.
Ключевые понятия
Стандарте не просто описывает язык С; он определяет пакет, состоящий из языка С, препроцессора С и стандартной библиотеки С. Препроцессор позволяет выполнить подготовительные действия перед компиляцией, указывая необходимые подстановки, выбирая строки кода, подлежащие компиляции, а также устанавливая другие аспекты поведения компилятора. Библиотека С расширяет возможности языка и предоставляет готовые решения для многих задач программирования.
Резюме
Препроцессор С и библиотека С представляют собой два важных дополнения языка С. Препроцессор С, следуя специальным директивам, нужным образом подстраивает исходный код перед его компиляцией. Библиотека С предоставляет множество функций, предназначенных для содействия в решении таких задач, как ввод, вывод, операции с файлами, управление памятью, сортировка и поиск, математические вычисления, обработка строк и множество других. В разделе V приложения Б содержит ся полный список функций библиотеки ANSI С.
712 глава 16
Вопросы для самоконтроля
Ответы на вопросы для самоконтроля приведены в приложении А.
1. Ниже приведены группы из одного или нескольких макросов, сопровождаемые строками кода, в которых они используются. Каким будет результат выполнения кода в каждом случае? Является ли код допустимым? (Предполагается, что переменные были объявлены.)
а. #define FPM 5280 /* футов в миле */
dist = FPM * miles;
б. #define FEET 4
#define POD FEET + FEET plort = FEET * POD;
B. #define SIX = 6; nex = SIX;
г #define NEW(X) X + 5 у = NEW(у);
berg = NEW(berg) * lob; est = NEW(berg) / NEW(y); nilp = lob * NEW(-berg);
2. Исправьте определение в части г) вопроса 1, чтобы сделать код более надежным.
3. Определите функциональный макрос, который возвращает меньшее из двух значений.
4. Определите макрос EVEN_GT (X, Y), который возвращает значение 1, если X является четным, а также больше Y.
5. Определите функциональный макрос, который выводит представления и значения двух целочисленных выражений. Например, он может выводить строку
3+4=7и4*12=48
если аргументами являются выражения 3 + 4и4*12.
6. Напишите операторы #def ine для достижения следующих целей.
а. Создайте именованную константу со значением 25.
б. Обеспечьте, чтобы идентификатор SPACE представлял символ пробела.
в. Обеспечьте, чтобы макрос PS() выводил символ пробела.
г. Обеспечьте, чтобы макрос BIG (X) представлял сложение 3 и X.
д. Обеспечьте, чтобы макрос SUMSQ (X, Y) представлял сумму квадратов X и Y.
7. Определите макрос, который выводит имя, значение и адрес переменной int в следующем формате:
имя: fop; значение: 23; адрес: ff46016
8. Предположим, что имеется блок кода, который необходимо пропустить во время тестирования программы. Как это сделать без удаления этого блока кода из файла?
9. Напишите фрагмент кода, который выводит дату обработки препроцессором, если макрос PR DATE определен.
Препроцессор и библиотека С 713
10. При обсуждении встраиваемых функций были показаны три разных версии функции square(). Чем они отличаются друг от друга в плане поведения?
11. Создайте макрос, используя выражение обобщенного выбора, которое оценивается в строку "boolean", если аргумент макроса имеет тип Bool, и в строку "not boolean" в противном случае.
12. Что неправильно в следующей программе?
#include
int main(int argc, char argv[])
{
printf("Квадратный корень из %f равен %f\n", argv[l], sqrt(argv[1]) );
}
13. Предположим, что scores — это массив из 1000 значений int, которые требуют сортировки в порядке убывания, а также, что вы используете функцию сортировки qsort() и функцию сравнения по имени comp().
а. Как правильно вызвать qsort() ?
б. Какое определение подойдет для comp() ?
14. Предположим, что datal — это массив из 100 значений double, a data2 — массив из 300 значений double.
а. Напишите вызов функции memcpy(), который скопирует первые 100 элементов data2 в datal.
Читать дальше