4.5. Объединение

"Объединение" означает соединение двух строковых констант в одну. При

работе с макросами, это означает объединение двух лексических единиц в одну

более длинную. Один аргумент макроса может быть объединен с другим аргументом

или с каким-либо текстом. Полученное значение может быть именем функции,

переменной или типа, а также ключевым словом С. Оно даже может быть именем

другого макроса.

При определении макроса, проверяется наличие операторов '##' в его

теле. При вызове макроса и после подстановки аргументов все операторы '##',

а также все пробелы рядом с ними (включая пробелы, принадлежащие аргументам)

удаляются. В результате производится объединение синтаксических конструкций

с обоих сторон оператора '##'.

Рассмотрим С программу, интерпретирующую указываемые команды. Для этого

должна существовать таблица команд, возможно массив из структур, описанный

следующим образом:

struct command

{

char *name;

void (*function) ();

};

struct command commands[] =

{

{ "quit", quit_command},

{ "help", help_command},

...

};

Более удобным будет не указывать имя каждой команды дважды: один раз

в строковой константе, второй - в имени функции. Макрос, принимающий в

качестве аргумента имя команды позволяет избежать это. Строковая константа

может быть создана с помощью стрингификации, а имя функции - путем

объединения аргумента со строкой '_command'. Ниже показано как это сделать:

#define COMMAND(NAME) { #NAME, NAME ## _command }

struct command commands[] =

{

COMMAND (quit),

COMMAND (help),

...

};

Обычным объединением является объединение двух имен (или имени и какого

либо числового значения) в одно. Также возможно объединение двух числовых

значений (или числового значения и имени) в одно. Операторы, состоящие из

нескольких символов (такие как '+='), также могут быть получены с помощью

объединения. В некоторых случаях возможно объединение строковых констант.

Однако, два текстовых значения, не образующих вместе правильной лексической

конструкции, не могут быть объединены. Например, объединение с одной стороны

символа 'x', а с другой - '+' является бессмысленным с точки зрения

формирования лексических конструкций С. В стандарте ANSI указано, что

подобный тип объединения не определен, хотя препроцессор GNU C их определяет.

В данном случае он помещает вместе символы 'x' и '+' вместе без каких либо

побочных эффектов.

Следует заметить, что препроцессор С преобразует все комментарии в

пробелы перед обработкой макросов. Поэтому нельзя создать комментарий

путем объединения '/' и '*' так как последовательность символов '/*' не

является лексической конструкцией. Также можно использовать комментарии в

макроопределениях после строки '##' или в объединяемых аргументах, так как

сначала комментарии заменяются на пробелы, а при объединении эти пробелы

игнорируются.

4.6. Удаление макросов

"Удалить" макрос означает отменить его определение. Это производится с

помощью директивы '#undef', за которой следует имя макроса.

Как и определение, удаление макросов появляется в определенном месте

исходного файла и вступает в силу с этого места. Например,

#define FOO 4

x = FOO;

#undef FOO

x = FOO;

заменяется на

 x = 4;

x = FOO;

В этом примере значение 'FOO' должно быть лучше переменной или

функцией, чем макросом, для получения после подстановки правильного С кода.

Директива '#undef' используется в такой же форме и для отмены

макроопределений с аргументами или без них. Применение этой директивы к

неопределенному макросу не дает никакого эффекта.

4.7. Переопределение макросов

"Переопределение" макроса означает определение (с помощью директивы

'#include') имени, которое уже было определено как макрос.

Переопределение явялется простым, если новое определение явно

идентично старому. Иногда не требуется специально выполнять простое

переопределение, хотя оно производится автоматически, если подключаемый

файл вкючается более одного раза, поэтому оно выполняется без какого-либо

эффекта.

Нетривиальные переопределения рассматриваются как возможная ошибка,

поэтому в таких случаях препроцессор выдает предупреждающее сообщение.

Однако, это иногда помогает при изменении определения макроса во время

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

запретить путем предварительного уничтожения макроса с помощью директивы

'#undef'.

Для простого переопределения новое определение долно точно совпадать

с предыдущим значением за исключением двух случаев:

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

Пробелы можно изменять в середине определения (но не в середине

строки). Однако они не могут быть полностью удалены, а также не могут быть

вставлены туда, где их не было вообще.


Информация о работе «Препроцессор языка C.»
Раздел: Информатика, программирование
Количество знаков с пробелами: 86051
Количество таблиц: 0
Количество изображений: 0

Похожие работы

Скачать
439386
0
0

... 1-12.   Напишите программу, печатающую гистограмму длин слов из файла ввода. Самое легкое - начертить гистограмму горизон- тально; вертикальная ориентация требует больших усилий. 1.7. Функции.   В языке “C” функции эквивалентны подпрограммам или функ- циям в фортране или процедурам в PL/1, паскале и т.д. Функ- ции дают удобный способ заключения некоторой части вычисле- ний в черный ...

Скачать
25582
0
0

... , сложны для понимания и абсолютно непрозрачны, а возможности существенно уступают Форту и Лиспу. В общем, муть и мрак. Вавилонское столпотворение Всякий раз, когда появляется очередной новый язык, о котором говорят, как об «окончательном и безальтернативном», предрекая скорую смерть всех остальных, мне становится смешно. Сам по себе язык в отрыве от среды программирования —малоинтересен, да и все ...

Скачать
668870
13
0

... программе. В данном разделе они перечислены в алфавитном порядке и приводятся с объяснениями. Эти ошибки могут являться следствием случайного затирание памяти программой. Abnormal program termination Аварийное завершение программы Данное сообщение может появляться, если для выполнения программы не может быть выделено достаточного количества памяти. Более подробно оно рассматривается в конце ...

Скачать
200759
5
11

... доступа с записью равной байту. Такие файлы называются двоичными. Файлы прямого доступа незаменимы при написании программ, которые должны работать с большими объемами информации, хранящимися на внешних устройствах. В основе обработке СУБД лежат файлы прямого доступа.  Кратко изложим основные положения работы с файлами прямого доступа. 1). Каждая запись в файле прямого доступа имеет свой номер ...

0 комментариев


Наверх