C/C++宏定义中的#
在C/C++中,宏定义是由define完成的,define中有三个特殊的符号值得我们注意:
1. #:在宏展开的时候会将#后面的参数替换成字符串,如:
#define p(exp) printf(#exp);
调用p(asdfsadf)的时候会将#exp换成”asdfsadf”
2. ##:将前后两个的单词拼接在一起。例如《The C Programming Language》中的例子:
#define cat(x,y) x##y
调用cat(var, 123)展开后成为var123.
3. #@:将值序列变为一个字符
#define ch(c) #@c
调用ch(a)展开后成为’a’.
当对于有参数列表的宏进行展开的时候,会先对参数进行收集,如果参数中又有宏定义,则系统会提取每个参数宏,对此逐个展开。
#define plus(x,y) x+y
在调用时,若使用plus(plus(1,2),3),按照顺序,该语句会被先展开变成plus(1+2,3) 而plus(1+2,3)仍然是个宏,继续展开,最后变成1+2+3。
《The C Programming Language》中说这里有两个例外,若调用宏中带有#或者##操作,参数宏不会被展开。例如:
#define cat(x,y) x##y
若这样调用cat(cat(1,2),3),结果是编译器报错。参数宏cat(1,2)不会被展开,结果是生成了cat(1,2)3,自然报错。
书中给出的解决办法是定义另外一个宏:
#define xcat(x,y) cat(x,y)
当执行xcat(xcat(1,2),3)将生成123,因为xcat自身的扩展不包括##的定义。
在展开的过程中,如果遇到相同的宏标示,宏的展开会停止。例如:
#define A A+1
结果停留在A+1。
Categories: Garfield's Diary