关于记号粘贴操作符(token paste operator): `##`

关于记号粘贴操作符(token paste operator): ##

1 简单的说, ##是一种分割连接方式, 它的作用是先分隔, 然后进行强制连接.

其中, 分隔的作用类似于空格. 我们知道在普通的宏定义中, 预处理器一般把空格解释成分段标志. 对每一段和前面比较,相同的就被替换. 但这样做的结果是, 被替换段之间存在一些空格. 如果我们不希望出现这些空格,就可以通过添加一些##来代替空格.

另外一些分隔标志是, 包括操作符, 比如 +,-,*,/,[,],..., 所以尽管下面的宏定义没有空格, 但是依然表达有意义的定义:

#define add(a,b) a+b

而其强制连接的作用是,去掉和前面的字符串之间的空格,而把两者连接起来.

2 举例 – 试比较下下述几个宏定义的区别

#define A1(name,type)   type name_##type##_type
#define A2(name, type)  type name##_##type##_type

A1(a1, int);  /* 等价于: int name_int_type; */ 
A2(a1, int);  /* 等价于: int a1_int_type;   */

解释:

(1). 在第一个宏定义中,name和第一个_之间,以及第2个_和第二个type之间没有被分隔,所以预处理器会把name_##type##_type解释成3段:name_type、以及_type,这中间只有type是在宏前面出现过的,所以它可以被宏替换.

(2). 而在第二个宏定义中,name和第一个_之间也被分隔了,所以预处理器会把 name##_##type##_type解释成4段:name_type以及_type,这其间,就有两个可以被宏替换了.

(3). A1和A2的定义也可以如下:

#define A1(name, type)  type name_  ##type ##_type      /* ##前面随意加上一些空格 */
#define A2(name, type)  type name ##_ ##type ##_type

结果是##会把前面的空格去掉完成强连接,得到和上面结果相同的宏定义

3 其他相关 – 单独的一个#

至于单独一个#,则表示对这个变量替换后,再加双引号引起来。比如:#define __stringify_1(x) #x. 那么, __stringify_1(linux) <==> "linux".

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值