使用宏打印空间和C中的#运算符

时间:2017-07-13 16:55:20

标签: c gcc macros

我正在使用宏并写了一个这样的:

#define STR(name) #name

我的意思是STR()将任何给它的字符串串作为参数,它似乎正在起作用。

printf( STR(Hello) )

按预期输出了输出:

Hello

所以

printf( STR(Hello world) );
printf( STR(String) STR(ise) );

给了

Hello world
Stringise

但是,当我尝试使用STR()打印空格时,它只是无效。

printf( STR(Hello) STR( ) STR(World) ); //There’s a space between the parenthesis of the second STR

输出:

HelloWorld

此处忽略STR( )

这是为什么?有没有办法围绕它使用,同时仍然坚持只有空格作为参数的宏?

我只是想知道这是否可能。

1 个答案:

答案 0 :(得分:3)

字符串化不可能导致单个空格。 #运算符的语义详见C11 6.10.3.2p2

  

如果在替换列表中,参数前面紧跟着#预处理标记,则它们都被单个字符串文字预处理标记替换,该标记包含相应参数的预处理标记序列的拼写。 参数的预处理标记之间每次出现的空格都会成为字符串文字中的单个空格字符。第一个预处理标记之前和构成参数的最后一个预处理标记之后的空格被删除。 [...] 对应于空参数的字符串文字是"" [...]

因此,由于空间不是预处理标记,并且删除了前导和尾随空格,因此字符串化运算符不可能创建仅包含单个空格的结果字符串文字。正如您所注意到的那样,STR( )会将一个空参数传递给宏,并将其字符串化为"";同样

STR(     Hello

World
)

将扩展为"Hello World";即每次出现的空白区域都将成为单个空格字符,并且前面和后面的空格将被删除。

但是,虽然无法对单个空格进行字符串化,但可以实现所需的输出。预处理器将连续的字符串文字标记连接成一个,因此"Hello" " " "World"将转换为“Hello world”;因此

printf(STR(Hello) " " STR(World));

将宏扩展扩展到

之后
printf("Hello" " " "World");

然后到

printf("Hello World");