Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЗФ_ОАиП / Лекции ГГУ Скорины - Программирование.doc
Скачиваний:
179
Добавлен:
21.03.2016
Размер:
2.27 Mб
Скачать

32.3 Директива условной компиляции

Исходный файл можно компилировать не целиком, а частями, используя директивы условной компиляции:

#define LEVEL 2

...

#if LEVEL > 3

текст1

#elif LEVEL > 1

текст2

#else

текст3

#endif

где LEVEL – это макроимя, поэтому выражение в директивах #if и #elif можно вычислить во время обработки исходного текста препроцессором.

Вычисляется константное целое выражение, заданное в строке #if. Если оно имеет ненулевое значение, то будут включены все последующие строки вплоть до ближайшей директивы #endif, #elif (действует как else if) или #else. Блок условной компиляции должен завершаться директивой #endif.

Получаем, если LEVEL больше 3, то компилироваться будет текст1, если LEVEL больше 1, то компилироваться будет текст2, в противном случае компилируется текст3.

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

Директив #elif может быть несколько (либо вообще ни одной), директива #else также может быть опущена.

Если все выражения, следующие за #if, #elif на данном уровне вложенности ложны (равны нулю), выбирается текст, следующий за #else. Если при этом ветвь #else отсутствует, никакой текст не выбирается.

В каком-то смысле директива #if похожа на условный оператор if. Однако, в отличие от него, условие – это константа, которая вычисляется на стадии препроцессора, и куски текста, не удовлетворяющие условию, просто игнорируются.

Можно использовать специальную препроцессорную операцию defined. Операция defined(идентификатор) дает ненулевое значение, если заданный идентификатор в данный момент определен; в противном случае выражение равно нулю (ложно). Операция может использоваться в сложном выражении и неоднократно:

#if defined(name1) || defined(name2)

Пример:

#if defined (COLOR)

color();

#elif defined (MONO)

mono();

#else

error();

#endif

Здесь условная директива управляет компиляцией одного из трех вызовов функции. Вызов функции color() компилируется, если определена именованная константа COLOR. Если определена константа MONO, компилируется вызов функции mono(), если ни одна из двух констант не определена, компилируется вызов функции error().

Чтобы застраховаться от повторного включения заголовочного файла my.h, этот файл можно оформить следующим образом:

#if !defined(MY_H)

#define MY_H

// здесь содержимое файла my.h

#endif

При первом включении файла my.h будет определено имя MY_H, а при последующих включениях препроцессор обнаружит, что имя MY_H уже определено, и перескочит сразу на #endif. Этот прием полезен, когда нужно избежать многократного включения одного и того же файла. Если им пользоваться систематически, то в результате каждый заголовочный файл будет сам включать заголовочные файлы, от которых он зависит, освободив от этого занятия пользователя.

Директива #ifdef – модификация условия компиляции. Условие считается выполненным, если указанное после нее макроимя определено. Соответственно, для директивы #ifndef условие выполнено, если имя не определено.

#define DEBUG 1

...

#if DEBUG

printf("%d", x);

#endif