- •Стадии препроцессорной обработки
- •Макроопределение без параметров
- •Пример:
- •Пример:
- •Пример:
- •Цепочка подстановок
- •Сравнение макросов и функций
- •Пример:
- •Пример:
- •Пример:
- •Int II, jj, ll; // целые внешние переменные
- •Условная компиляция
- •Пример:
- •Пример:
- •Пример:
- •Вспомогательные директивы
- •Пример:
- •Void main ( ) // строка 2
- •Пример:
Пример:
После определения идентификатора DEBUG с помощью директивы
#define DEBUG
В программе можно использовать для вывода контрольного сообщения конструкцию
#ifdef DEBUG
printf ( “Отладочная печать”);
#endif
Оператор printf ( “Отладочная печать”); выполняется, т.к. идентификатор DEBUG ранее определен. Вывод контрольного сообщения может использоваться программе неоднократно, но убрав либо поместив в скобки комментария директиву #define DEBUG, можно отключить их все сразу.
Директива #ifndef часто применяется для того, чтобы не происходило повторного включения файлов, текст которых вставляется в программу директивой #include. Такая ситуация может иметь место, когда в одну программу подключаются несколько файлов, в каждом из которых, в свою очередь, подключается один и тот же файл. Чтобы этого не произошло, в каждый файл необходимо включить специальные средства защиты от повторного включения. Такими средствами защиты снабжены все заголовочные файлы стандартной библиотеки.
Пример:
#ifndef _FILE_NAME // проверка определенности _FILE_NAME
#include "filename.h" // включение текста файла filename.h
#define _FILE_NAME // определение _FILE_NAME
#endif
Здесь _FILE_NAME - зарезервированный для файла с именем filename препроцессорный идентификатор. Его нежелательно использовать в других текстах программы.
Директива #elif является составной директивой #else - #if. Она используется для организации множественных ветвлений.
Данная директива имеет формат
#elif выражение
Требования к выражению такие же, как и для директивы #if.
Формат применения данной директивы:
#if выражение_0
текст_для_if
#elif выражение_1
текст_1
#elif выражение_2
текст_2
…
#else
текст_для__еlse
#endif
Количество директив #elif является произвольным.
Препроцессор сначала проверяет выражение_0 в директиве #if. Если оно не равно 0, в компилируемый текст включается текст_для_if, если оно равно 0, вычисляется выражение_1. Если выражение_1 не равно 0 в текст включается текст_1, если оно равно 0, вычисляется выражение_2 и т.д. Если все выражения равны 0, то в компилируемый текст включается текст_для_else.
При появлении ненулевого выражения в одной из директив (#if или #elif) в компилируемый текст включается текст, расположенный после данной директивы, а все остальные директивы не рассматриваются. Таким образом, в компилируемый текст включается всегда только один из участков текста, выделенных директивами условной компиляции. Это бывает полезно при отладке или, например, при поддержке нескольких версий программы для различных платформ.
Пример:
#if VERSION == 1
#define INCFILE "versl.h"
#elif VERSION ==2
#define INCFILE "vers2.h"
#else
#define INCFILE "vers3.h"
#endif
#include INCFILE
В данном примере выполняется включения различных версий заголовочного файла.
Операция defined
При использовании директив #if и #elif для упрощения записи сложного условия выбора можно использовать унарную препроцессорную операцию defined. Она имеет формат:
defined операнд
В качестве операнда может выступать идентификатор, заключенный в скобки идентификатор и вызов макроса. Выражение принимает значение 1, если идентификатор является препроцессорным (ранее определен директивой #define), в противном случае - значение 0.
Выражение
#if defined операнд
эквивалентно выражению
#ifdef операнд
При рассмотрении такого простого случая достоинства операции defined не проявляются. Поясним с помощью примера полезные возможности операции defined.