Menu

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

Comments