C/C++宏字符串连接
#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
是否可以将 STR1
和 STR2
连接到 "s1"
? 您可以通过将参数传递给另一个宏函数来完成此操作。但有没有直接的方法呢?
#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Is it possible to concatenate STR1
and STR2
, to "s1"
?
You can do this by passing args to another Macro function. But is there a direct way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果它们都是字符串,您可以这样做:
这然后扩展为:
在 C 语言中,用空格分隔两个字符串,如
"s" "1"
完全等同于拥有单个字符串“s1”
。If they're both strings you can just do:
This then expands to:
and in the C language, separating two strings with space as in
"s" "1"
is exactly equivalent to having a single string"s1"
.您不需要针对字符串文字的此类解决方案,因为它们是在语言级别连接的,而且无论如何它都不起作用,因为“s”“1”不是有效的预处理器标记。
[编辑:为了回应下面错误的“仅供记录”评论,不幸的是收到了一些赞成票,我将重申上面的声明,并观察到程序片段
在 gcc 的预处理阶段产生了此错误消息:错误:粘贴“”s”和“”1”不会给出有效的预处理标记
]
但是,对于一般标记粘贴,请尝试以下操作:
然后,例如,
PPCAT_NX(s, 1)
PPCAT_NX(s, 1) 和PPCAT(s, 1)
生成标识符s1
,除非s
被定义为宏,在这种情况下PPCAT (s, 1)
产生1。继续主题是这些宏:
然后,
相比之下,
You don't need that sort of solution for string literals, since they are concatenated at the language level, and it wouldn't work anyway because "s""1" isn't a valid preprocessor token.
[Edit: In response to the incorrect "Just for the record" comment below that unfortunately received several upvotes, I will reiterate the statement above and observe that the program fragment
produces this error message from the preprocessing phase of gcc: error: pasting ""s"" and ""1"" does not give a valid preprocessing token
]
However, for general token pasting, try this:
Then, e.g., both
PPCAT_NX(s, 1)
andPPCAT(s, 1)
produce the identifiers1
, unlesss
is defined as a macro, in which casePPCAT(s, 1)
produces<macro value of s>1
.Continuing on the theme are these macros:
Then,
By contrast,
提示:上面的
STRINGIZE
宏很酷,但是如果您犯了一个错误,并且它的参数不是宏 - 您的名称有拼写错误,或者忘记了#include
头文件 - 那么编译器会很高兴地将所谓的宏名称放入字符串中,不会出现错误。如果您希望 STRINGIZE 的参数始终是具有普通 C 值的宏,则将
其展开一次并检查其有效性,丢弃它,然后再次将其展开为字符串。
我花了一段时间才弄清楚为什么
STRINGIZE(ENOENT)
最终成为"ENOENT"
而不是"2"
...我没有包含errno.h
。Hint: The
STRINGIZE
macro above is cool, but if you make a mistake and its argument isn't a macro - you had a typo in the name, or forgot to#include
the header file - then the compiler will happily put the purported macro name into the string with no error.If you intend that the argument to
STRINGIZE
is always a macro with a normal C value, thenwill expand it once and check it for validity, discard that, and then expand it again into a string.
It took me a while to figure out why
STRINGIZE(ENOENT)
was ending up as"ENOENT"
instead of"2"
... I hadn't includederrno.h
.