【问题标题】:What does 'a ## b' mean in C? [duplicate]'a ## b' 在 C 中是什么意思? [复制]
【发布时间】:2014-12-21 23:03:53
【问题描述】:

来自 usbtiny/defs.h(ATTiny 控制器的 AVR libc USB 代码):

#define CAT2(a,b)               CAT2EXP(a, b)
#define CAT2EXP(a,b)            a ## b
#define CAT3(a,b,c)             CAT3EXP(a, b, c)
#define CAT3EXP(a,b,c)          a ## b ## c

## 运算符是什么?我已经这样做了 30 年,我很困惑。谷歌没有帮助,因为我认为他们没有为这些字符编制索引。

【问题讨论】:

  • @karthikr:不完全是,额外的间接性很重要。
  • 在此处的搜索框中输入[c] "##"引号),您会找到很多相关信息。

标签: c


【解决方案1】:

宏定义中的## 符号表示连接。

所以

#define concat(a,b) a ## b

意思是

concat (pri, ntf) ("hello world\n");

后期处理

printf("hello world\n");

文档here

stringify 运算符 (#) 也很有用,不要与它混淆。

测试:

/* test with
 *    gcc -E test.c
 * having removed the #include lines for easier to read output
 */

#include <stdio.h>
#include <stdlib.h>

#define concat(a,b) a ## b

int
main (int argc, char **argv)
{
  concat (pri, ntf) ("Hello world\n");
  exit (0);
}

为什么要增加额外的间接级别?正如 Deduplicator 在 cmets 中对他下面的答案指出的那样,如果没有它,它将连接指定的字面术语,而不是宏替换的术语。此类陷阱的有用列表是here

【讨论】:

  • 谢谢。这就是我需要知道的。
  • 换句话说,它是一种从子代币中构建代币的方式。
【解决方案2】:

CAT2CAT3 是应该调用的宏,另外两个是它们内部工作的一部分。

#define CAT2(a,b)               CAT2EXP(a, b)
#define CAT2EXP(a,b)            a ## b

那么,如果你打电话给CAT2,会发生什么?

好吧,首先 CAT2 被替换,它宏扩展了文字参数:

CAT2(a_eval, b_eval)

## 标记连接运算符连接两个参数以生成一个标记。

【讨论】:

  • @nsayer;不是吗?额外的间接性很重要,即使您还没有认识到它,因此没有明确询问它。
  • 我赞成这是你说的为什么额外的间接级别很重要。我同意,因为我以前遇到过这个,但我不记得为什么了。
  • @abligh:否则文字参数将被连接,而不是在可能的宏替换之后。
  • @abligh:假设你说的是#define N 3,那么CAT2EXP(A,N) 就是AN,而CAT2(A,N) 就是A3。 (反之亦然,我不确定:)
  • @Deduplicator - 是的,就是这样。 Upvote 正式交付。
猜你喜欢
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 2020-02-09
  • 2014-01-16
  • 1970-01-01
  • 2017-02-02
相关资源
最近更新 更多