Поделиться через


Строковый оператор (#)

Знак решетки (#), или строковый оператор, преобразует параметры макроса в строковые литералы без развертывания определения параметра. Он используется только с макросами, которые принимают аргументы. Если он стоит перед формальным параметром в определении макроса, то фактический аргумент, передаваемый вызовом макроса, заключается в кавычки и обрабатывается как строковый литерал. Далее этим строковым литералом заменяется каждое сочетание строкового оператора с формальным параметром, которое встречается в определении макроса.

Примечание

Расширение Microsoft C (версии 6.0 и более ранних) для стандарта ANSI C, которое ранее развертывало формальные аргументы макросов в строковых литералах и символьных константах, больше не поддерживается.Код, в котором использовалось это расширение, необходимо переписать с использованием строкового оператора (#).

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

Если содержащийся в аргументе символ — например, знак кавычки (") или обратная косая черта (\) — обычно требует escape-последовательности для использования в строковых литералах, то перед этим символом автоматически подставляется обратная косая черта (символ escape-последовательности).

В Visual C++ поведение строкового оператора может в некоторых ситуациях отличаться; дополнительные сведения см. в разделе 16.3.2 Оператор #.

Пример

В приведенном ниже примере показано определение макроса, в котором содержится строковый оператор, а также функция main, которая вызывает этот макрос.

Такие вызовы будут развернуты во время предварительной работки. В результате будет создан следующий код:

int main() {
   printf_s( "In quotes in the printf function call\n" "\n" );
   printf_s( "\"In quotes when printed to the screen\"\n" "\n" );
   printf_s( "\"This: \\\" prints an escaped double quote\"" "\n" );
}

// stringizer.cpp
#include <stdio.h>
#define stringer( x ) printf_s( #x "\n" )
int main() {
   stringer( In quotes in the printf function call ); 
   stringer( "In quotes when printed to the screen" );   
   stringer( "This: \"  prints an escaped double quote" );
}
  

В следующем примере показано, как развернуть параметр макроса:

// stringizer_2.cpp
// compile with: /E
#define F abc
#define B def
#define FB(arg) #arg
#define FB1(arg) FB(arg)
FB(F B)
FB1(F B)

См. также

Ссылки

Операторы препроцессора