Условные директивы

Условная компиляция

Включение текстов из файлов

Для включения текста из файла используется команда #include, имеющая три формы записи:

#include < имя_файла > /* Имя в угловых скобках */

#include "имя_файла" /* Имя в кавычках */

#include имя_макроса

/* Макрос, расширяемыи до обозначения файла*/

где имя_макроса - это введенный директивой #define препроцессорный идентификатор либо макрос, при замене которого после конечного числа подстановок будет получена последовательность символов <имя_файла> либо "имя_файла".

До сих пор мы в программах и примерах фрагментов программ использовали только первую форму команды #include. Существует правило, что если имя_файла - в угловых скобках, то препроцессор разыскивает файл в стандартных системных каталогах. Если имя_файла заключено в кавычки, то вначале препроцессор просматривает текущий каталог пользователя и только затем обращается к просмотру стандартных системных каталогов.

Директивы ветвлений. Условная компиляция обеспечивается в языке Си следующим набором директив, которые, не точно соответствуя названию, управляют не компиляцией, а препроцессорной обработкой текста:

#if целочисленное_константное_выражение

#ifdef идентификатор

#ifndef идентификатор

#else

#endif

#elif

Первые три директивы выполняют проверку условии, две следующие - позволяют определить диапазон действия проверяемого условия. (Директиву #elif рассмотрим несколько позже.) Общая структура применения директив условной компиляции такова:

#if...

текст_1

#else

текст_2

#endif

Конструкция #else текст_2 необязательна. Текст_1 включается в компилируемый текст только при истинности проверяемого условия (обозначено многоточием после #if). Если условие ложно, то при наличии директивы #else на компиляцию передается текст 2.

#if целочисленное_константное_выражение

Здесь проверяется значение константного выражения, в которое могут входить целые константы и идентификаторы. Идентификаторы могут быть определены на препроцессорном уровне, и тогда их значение определяется подстановками. В противном случае считается, что идентификаторы имеют нулевые значения. Если константное выражение отлично от нуля, то считается, что проверяемое условие истинно.

#ifdef идентификатор

Проверяется, определен ли с помощью директивы #define к текущему моменту идентификатор, помещенный после #ifdef. Если идентификатор определен, т.е. является препроцессорным, то текст 1 используется компилятором.

#ifndef идентификатор

Проверяется обратное условие - истинным считается неопределенность идентификатора, т.е. тот случай, когда идентификатор те был использован в команде #define или его определение было отменено командой #undef.

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

#elif целочисленное_константное_выражение

Структура исходного текста с применением этой директивы #elif:

#if условие текст_для_if

#elif выражение_1 текст_1

#elif выражение_2 текст_2

#elif выражение_3

текст_3

...

#else

текст_для_случая_else

#endif

Препроцессор проверяет вначале условие в директиве #if. Если оно ложно (равно 0), - вычисляется выражение_1, если при этом оказывается, что и значением выражения_1 также равно 0, - вычисляется выражение_2, и т.д.

Таким образом, препроцессор обрабатывает всегда только один из участков текста, выделенных директивами условной компиляции.