C语言中的#和##
#是在宏定义中将参数进行字符串化的预处理特征,例如:
#include <iostream> using namespace std; #define P(EXP) cout<<#EXP<<":"<<EXP<<endl int main() { int a=123; float f=123.456; P(a); P(f); P(23); return 0; }
这样可以把不同变量的值和名称打印出来,上面的例子显示为:
a:123
f:123.456
23:23
##是连接符,例如:
#include <iostream> using namespace std; #define V(x) var##x int main() { int var1=123,var2=222,var3=321; printf("%d\n",V(1)); printf("%d\n",V(2)); printf("%d\n",V(3)); return 0; }
显示为:
123
222
321
这个例子可能不是太好,感觉很鸡肋,不过在很多的嵌入式开发中,有很多诸如GPIOA、GPIOB等端口时,使用这种方式就比较方便了。
注意:
当宏参数是另一个宏的时候,需要注意的是,凡宏定义里有用’#’或’##’的地方宏参数是不会再展开,看下面的例子:
#include <iostream> using namespace std; #define V(x) var##x int main() { int P=1; int var1=123,var2=222,var3=321; printf("%d\n",V(P)); return 0; }
这段代码无法通过编译,报错为:error: 'varP' was not declared in this scope
当然,更不要幻想使用宏定义确定P:
#include <iostream> using namespace std; #define V(x) var##x #define P 1 int main() { int var1=123,var2=222,var3=321; printf("%d\n",V(P)); return 0; }
报出的错误是相同的。
预处理的替换,只会做最简单的浅层替换,而不会去考虑这个字符串是从哪里来的