НазадОглавлениеДалее

7.2.2. Склейка лексем и преобразование аргументов макроопределений

СП ТС и версия 5.0 СП MSC реализуют две специальные препроцессорные операции: ## и #.

В директиве #define две лексемы могут быть "склеены" вместе. Для этого их нужно разделить знаками ## (слева и справа от ## допустимы пробельные символы). Препроцессор объединяет такие лексемы в одну; например, макроопределение

#define VAR(i, j) i##j

при макровызове VAR(x, 6) образует идентификатор х6. Некоторые компиляторы позволяют в аналогичных целях употребить запись х/**/6, но этот метод менее переносим.

Символ #, помещаемый перед аргументом макроопределения, указывает на необходимость преобразования его в символьную строку. При макровызове конструкция #<формальный параметр> заменяется на "<фактический аргумент>".

Пример: макроопределение TRACE позволяет печатать с помощью стандартной функции printf значения переменных типа int в формате <имя>=<значение>.

#define TRACE(flag) printf(#flag "=%d\n", flag)

Следующий фрагмент текста программы:

highval=1024;

TRACE(highval);

примет после обработки препроцессором вид:

highval=1024;

printf("highval" "=%d\n", highval);

Следующие друг за другом символьные строки рассматриваются компилятором языка Си в СП MSC версии 5 и в СП ТС как одна строка, поэтому полученная запись эквивалентна следующей:

highval=1024;

printf("highval=%d\n", highval);

При макровызове сначала выполняется макроподстановка всех аргументов макровызова, а затем их подстановка в тело макроопределения. Поэтому следующая программа напечатает строку "отклонение от стандарта"

main ()

{

#define AB "стандарт"

#define А "отклонение"

#define В " от стандарта"

#define CONCAT(P, Q) P ## Q

printf(CONCAT(A, В) "\n");

}


НазадОглавлениеДалее