一般的宏嵌套展开规则是由内向外,先将内层宏展开,再把外层宏展开:
#include #define A(x) (x + 5)#define B(x) (x * 5)void main(void){ printf(“%dr”, B(A(2)));}
输出:
35
嵌套宏B(A(2))会先展开为B((2 + 5)),然后再展开为((2 + 5) * 5),所以最终结果为35
如果宏的参数直接带有#,则不会展开内层的嵌套宏
#include #define STR(x) #x#define TO_STR(x) STR(x)#define ADD(a, b) (a + b)void main(void){ printf(“%sr”, STR(ADD(3, 4))); printf(“%sr”, TO_STR(ADD(3, 4)));}
输出:
ADD(3, 4)(3 + 4)
因为STR宏的参数直接带有#,所以STR内部嵌套的内容不会被进一步展开,故STR(ADD(3, 4))输出为ADD(3, 4);
因为TO_STR宏的内容并没有#,所以嵌套的宏ADD(3, 4)依旧可以展开,故TO_STR(ADD(3, 4))输出结果为(3 + 4);
如果宏的参数直接带有##,则会先将参数通过##拼接,然后再依次进行展开
#include #define STR(x)#x#define TO_STR(x)STR(x)#define DEF_VAR(a)var_##a#define PARAM(x)param_##xvoid main(void){ printf(“%sr”, TO_STR(DEF_VAR(PARAM(10))));}
输出:
var_PARAM(10)
由于DEF_VAR中带有##所以会先将里面的内容使用##拼接,所以会最先展开为TO_STR(var_PARAM(10)),由于展开后PARAM(10)已经变成了var_PARAM(10),已经不是有效的宏了,所以最终再经过TO_STR的转换后,结果就是var_PARAM(10)