【问题标题】:Printing space with a macro and # operator in C在 C 中使用宏和 # 运算符打印空间
【发布时间】:2017-07-13 16:55:19
【问题描述】:

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

#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( ) 被忽略了。

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

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

【问题讨论】:

  • @DavidC.Rankin 我做到了。 printf( STR(Hello) STR(" ") STR(world) );Hello" "world 一样打印引号。我只想要空间。
  • STR( ) --> " "
  • @J...S - 啊 - 它也打印文字引号。这是个问题:)
  • 空白不是实际参数。类似于,
  • 你能给出这样一个#define的理由吗?你为什么要努力让你的生活变得更艰难?>

标签: c gcc macros


【解决方案1】:

字符串化不可能产生单个空格。 # 运算符的语义详见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");

【讨论】:

  • 这个问题是关于宏和# 运算符的。我不明白这是如何回答这个问题的。
  • @Olaf 现已修复。
  • 感谢您引用定义此行为的标准部分。
  • @AnttiHaapala “预处理器将连续的字符串文字标记连接成一个”我认为这不是真的。串联(第 6 阶段)发生在预处理器(第 4 阶段)之后。
猜你喜欢
  • 2022-12-31
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 2013-01-17
  • 2010-09-15
相关资源
最近更新 更多