ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4266
Скачиваний: 28
Глава 8. Типы данных, определяемые программистом
121
типы, то для сравнения функций также необходимо, чтобы они
имели одинаковое количество параметров и типы этих парамет-
ров были сравнимы.
В заключение этого раздела отметим, что одинаковые квалифи-
каторы типов
const
или
volatile
не нарушают сравнимость ти-
пов. Разные квалификаторы типов или отсутствие квалификатора
у одного из типов делает эти типы не сравнимыми.
Г Л А В А
9
Директивы препроцессора
9.1. Препроцессор
Препроцессором
называется программа, которая вызывается
компилятором и обрабатывает исходную программу перед ее
компиляцией. Эта программа различает специальные команды,
которые называются
директивами
. Строка с директивой отмеча-
ется символом
#
, который должен быть первым не пробельным
символом строки. Этот символ не является составной частью ди-
рективы, а только указывает, что данная строка содержит дирек-
тиву препроцессора. Поэтому после символа
#
могут распола-
гаться пробелы. Заканчивается директива символом перехода на
новую строку
\n
. Если перед символом перехода на новую строку
встретился символ
\
, то препроцессор считает, что директива
продолжается на следующей строке.
После обработки директив препроцессором исходный текст про-
граммы передается для обработки компилятору. Отметим также,
что препроцессор различает все лексемы языка программирова-
ния С.
Препроцессор языка С обрабатывает следующие директивы:
#if #else #elif #endif
#define #undef #ifdef #ifndef
#error #include #line #pragma
а также операторы
#
и
##
, которые и будут рассмотрены в этой
главе.
Глава 9. Директивы препроцессора
123
9.2. Директивы
#define
и
#undef
Директива
#define
определяет символическое имя для констант и
выражений языка программирования С. Такое определение назы-
вается
макроопределением
, а символическое имя —
макросом
.
Если определяется символическое имя константы, то директива
#define
имеет следующий вид:
#define имя константа
Здесь
имя
определяет символическое имя для
константы
языка
программирования С. В этом случае символическое имя также
называется
символической константой
. Например, директива:
#define MAX_VAL 255
определяет символическое имя
MAX_VAL
для целочисленной кон-
станты
255
.
Если определяется символическое имя выражения, то директива
#define
имеет следующий вид:
#define имя(список_параметров) выражение
Здесь
имя
является символическим именем для
выражения
языка
программирования С, а
список_параметров
содержит параметры,
которые разделены запятыми и входят в
выражение
. В этом случае
символическое имя также называется
макрокомандой
. Например,
следующая директива:
#define MUL(a, b) ((a)*(b))
определяет макрокоманду для умножения двух чисел.
При определении макрокоманды ее параметры следует брать в
круглые скобки, чтобы избежать возможных ошибок. Например,
в следующем примере:
#define MUL(a, b) (a*b)
int n = MUL(1+2, 2+1); /* с = 1+2*2+1 = 6 */
Переменная
n
инициализируется числом
6
, что явно противоре-
чит намерениям программиста.
Часть I. Язык программирования С
124
При помощи директивы
#define
можно также определить макро-
команду для вызова функции. Например, следующая директива:
#define print_int(val) printf("%d\n", val)
определяет символическое имя для функции, которая печатает
значение целочисленного выражения. Теперь напечатать цело-
численное значение можно так:
print_int(10);
Используются символические имена только после их определе-
ния. Если препроцессор встретит в исходном файле программы
определенное символическое имя, то он заменит его соответст-
вующим текстовым значением. По соглашению символические
имена определяются прописными буквами.
Директива
#undef
служит для отмены определения символиче-
ского имени и имеет следующий синтаксис:
#undef имя
После исполнения этой директивы символическое
имя
нельзя ис-
пользовать в программе. Например:
#undef MAX_VAL
#undef MUL
9.3. Директивы
#if
,
#elsif
,
#else
и
#endif
Директивы
#if
,
#elsif
,
#else
и
#endif
используются для условно-
го включения и исключения фрагментов исходного кода в текст
программы.
Директива
#if
служит для вставки в текст программы фрагмента
исходного кода в зависимости от истинностного значения выра-
жения. Значение выражения считается истинным, если оно не
равно нулю. Завершение фрагмента исходного кода отмечается
директивой
#endif
.
Синтаксис директив
#if
и
#endif
имеет следующий вид:
#if выражение
исходный_код
#endif
Глава 9. Директивы препроцессора
125
Здесь
выражение
должно быть целочисленным константным вы-
ражением, а
исходный_код
— это исходный код на языке програм-
мирования С. Этот код вставляется в текст программы, если зна-
чение выражения истинно. В противном случае текст программы
не изменяется.
Пример использования директив
#if
и
#endif
приведен в листин-
ге 9.1.
Листинг 9.1. Пример использования директив
#if
и
#endif
#include <stdio.h>
#define MAX_VAL 255
int main(void)
{
int n = 10;
#if MAX_VAL > 20
n = 20;
#endif
printf("n = %d\n", n); /* n = 20 */
return 0;
}
Директива
#else
используется только с директивой
#if
и служит
для вставки в текст программы фрагмента исходного кода, если
истинностное значение выражения в директиве
#if
ложно. Ком-
бинация директив
#if
и
#else
имеет следующий вид:
#if выражение
исходный_код_1
#else
исходный_код_2
#endif
Если значение
выражения
ложно, то в текст программы вставляет-
ся
исходный_код_2
. Например:
#define VERSION 2
#if VERSION > 2
printf("Version = %d\n", 3);