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

Макроопределение без параметров

Про­стейшее макроопределение с помощью директивы #define имеет вид:

#define идентификатор строка_замещения

С помощью такого макроопределения задается препроцессорный макрос без параметров. Идентификатор задает имя макроса. Данное имя используется для обращения к макросу. В результате работы препроцессора все вхождения указанного идентификатора в тексте программы заменяются на символьную последовательность, задаваемую строкой замещения. Сим­волы пробелов, помещенные в начале и в конце строки замещения, в подстановке не используются. Данный процесс называется макровызовом (вызовом макроса).

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

Пример:

Исходный текст Результат препроцессорной обработки

#define begin {

#define end }

void main( ) void main( )

begin {

операторы операторы

end }

В исходном тексте программы в качестве операторных скобок используются идентификаторы begin, end. Препроцессор заменяет все вхождения данных идентификаторов стандартными скобками { и }. Выполненные директивы #define из текста исключаются.

Если строка замещения является слишком длинной, она может быть перенесена на следующую строку. Это можно осуществить, поместив символ ‘\’ в конце продолжаемой строки. В ходе второй стадии препроцессорной обработки этот символ вместе с последующим символом конца строки будет удален из текста программы.

Пример:

#define STRING "\n Game Over! - \

Игра закончена!"

printf (STRING);

На экран будет выведено:

Game Over! - Игра закончена!

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

Действие макроподстановок, выполняемых согласно с директивой #define, имеет ряд ограничений. Замены не выполняются внутри:

  • комментариев (строк, ограниченных символами /* и */ или записанных после знака //),

  • символьных констант (символов, ограничен­ных апострофами '),

  • строковых констант (строк, ограниченных двойными кавычками "),

  • внутри идентификаторов (часть идентификатора не может быть заменена).

Пример:

#define n 24

char с = '\n'; // c - cимвольная константа, \n - escape-последовательность

c = ‘n’ > ‘\n’?'\n':'\n'

int k = n;

В ходе препроцессорной обработки данного текста замена идентификатора n на число 24 будет выполнена только один раз в последнем определении, которое примет вид:

int k=24;

Все остальные вхождения символа n в составе строковых констант препроцессором будут проигнорированы.

В строке замещения символы /*, */, //, ', " могут присутствовать (например, как в строке замещения макроса STRING).

Строку замещения, связанную с конкретным препроцессорным идентификатором, можно сменить, приписав уже определенному идентификатору новое значение другой командой #define:

#define M 16 // идентификатор М определен как 16

#define M ‘С’ // идентификатор М определен как символьная константа ‘С’

#define M “С”

/* идентификатор М определен как строковая константа */

/* с двумя элементами: ‘С’и ‘\0’ */

Однако при таких сменах значений препроцессорного иден­тификатора компилятор выдает предупреждающее сообщение на каждую следующую директиву #define:

Warning ..: Redefinition of 'M' is not identical