Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Директивы препроцессора.doc
Скачиваний:
7
Добавлен:
20.07.2019
Размер:
206.34 Кб
Скачать

Пример:

#if defined Y && !defined N

текст

#endif

Текст включается в компилируемый текст только в том случае, если идентификатор Y определен как препроцес­сорный, а идентификатор N не определен.

Обработку препроцессор ведет следующим образом. Сначала, определяется истинность выражений defined Y и !defined N. К резуль­татам применяется операция конъюнкции &&, и при истинно­сти ее результата текст передается компилятору.

Не используя операцию defined, то же самое условие можно записать таким способом:

#ifdef Y

#ifndef N

текст

#endif

#endif

Таким образом, из примера видно, что

#if defined эквивалентно #ifdef

#if !defined эквивалентно #ifndef

Стандарт языка С++ не определил defined в качестве ключе­вого слова. В тексте программы его можно использовать в каче­стве идентификатора. Специфическое значение имеет defined только при формировании условий, проверяе­мых в директивах #if и #elif. Запрещено использовать defined в директивах #define и #undef.

Вспомогательные директивы

Кроме рассмотренных ранее директив #include, #define и директив ко­манд условной компиляции существует еще несколько вспомогательных директив, которые не так часто используются в практике программирования.

Директива #line позволяет управлять нумерацией строк в файле с программой, а также изменять имя файла.

После препроцессорной обработки каждая строка текста передаваемого на компиляцию имеет следующий вид:

имя_файла номер_строки: текст_на_языке_С++

Директива #line имеет следующий формат:

Для нумерации строк можно использовать директиву

#line номер_строки [“имя_файла”]

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

Пример:

Препроцессор получает для обработки файл "www.c" с текстом:

#define N 3 // строка 1

Void main ( ) // строка 2

{ // строка 3

#line 23 "file.с" // строка 4

double z[3*N]; // строка 5

} // строка 6

После препроцессорной обработки в файле с именем "www.i" будет получен следующий набор строк:

www.c 1:

www.c 2: void main ( )

www.c 3: {

www.c 4:

file.c 23: double z[3*3]

file.c 24: }

Из текста исключены препроцессорные директивы и комментарии. При этом строки, где размещались директивы препроцессора (1 и 4), вошли в компилируемый текст, как пустые строки. Следующей за ди­рективой #line строке присвоен номер 23 и имя файла "file.c" в соответствие с указанными значениями. Следующая строка имеет такое же имя файла и номер строки на единицу больше.

Директива #line может использоваться в случае, когда текст программы на языке С++ генерирует какой-то другой препроцессор.

Директива #error задает текст сообщения, которое выводится при возникновении ошибок компиляции.

Она имеет следующий формат:

#error текст_сообщения

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

Пример:

Определив некоторую препроцессорную переменную NAME

#define NAME 5

можно проверять, не изменилось ли ее значение, и выдавать в этом случае сообще­ние:

#if (NAME != 5)

#error NAME должно быть равно 5

В интегрированной среде (например, Turbo С) сообщение будет выдано на этапе компиляции в виде:

Fatal <имя_файла> <номер_строки>:

Error directive: NAME должно быть равно 5

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

Директива #pragma вызывает действия, зависящие от конкретной реализации компилятора.

Она имеет следующий формат

#pragma последовательность _лексем

Данная конструкция называется прагмой. Стандарта для прагм не существует. Если конкретный препроцессор встречает прагму, которая ему неиз­вестна, он ее игнорирует.

В неко­торых реализациях включена директива

#pragma pack(n)

n может быть равно 1, 2 или 4.

Данная прагма позволяет влиять на упаковку смежных эле­ментов в структурах и объединениях. Соглашение может быть таким:

pack(l) - выравнивание элементов по границам байтов;

раск(2) - выравнивание элементов по границам слов;

раск(4) - выравнивание элементов по границам двойных слов.

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

Существует также пустая директива, использование которой не вызывает никаких действий. Она имеет вид:

#