在C中粘贴的令牌不清楚

时间:2014-01-10 12:04:10

标签: c c-preprocessor

#include <stdio.h>

#define tokenpaster(n) printf ("token" #n " = %d", token##n)

int main(void)
{
   int token34 = 40;

   tokenpaster(34);
   return 0;
}

The output is

token34 = 40

作者说:

如何发生,因为此示例导致预处理器的以下实际输出:

printf ("token34 = %d", token34);

token##n如何转换为token34?它不应该是token#34吗?

2 个答案:

答案 0 :(得分:2)

预处理程序语句中的双哈希将两个参数粘合在一起。因此token##n变为token##34变为token34。单个哈希对其参数进行字符串化。因此#n变为"34"。因此整个宏观扩张如下:

tokenparser(34);
->
printf ("token" #n " = %d", token##n);
->
printf ("token" "34" " = %d", token##34);
->
printf ("token" "34" " = %d", token34);

并且编译器连接格式字符串,因此最终结果为:

printf ("token34 = %d", token34);

答案 1 :(得分:0)

单个哈希前缀(#)强制预处理器为stringify您的参数。双重哈希前缀(##)只是粘贴参数并将其与前缀合并。

这意味着tokenpaster(34)将扩展为:

printf ("token" "34" " = %d", token34)
                ^^^^               ^^
                  |                 |
                  |                 +---- pasted and merged
                  |
                  +---- enclosed in quotes

然后将这三个字符串文字部分合并为一个文字:

printf ("token34 = %d", token34)

根据the standard

  

§6.10.3.2#运算符

     

2如果在替换列表中,参数前面紧跟#预处理   令牌,两者都被单字符串文字预处理令牌取代   包含相应的预处理标记序列的拼写   论点。 (...)

  

§6.10.3.3##运算符

     

2如果在类似函数的宏的替换列表中,紧接着一个参数   或者后跟##预处理令牌,参数将被相应的替换   参数的预处理标记序列(...)