一般的宏嵌套展开规则是由内向外,先将内层宏展开,再把外层宏展开:
#include <stdio.h>
#define A(x) (x + 5)
#define B(x) (x * 5)
void main(void)
{
printf("%d\r\n", B(A(2)));
}
输出:
35
嵌套宏B(A(2))
会先展开为B((2 + 5))
,然后再展开为((2 + 5) * 5)
,所以最终结果为35
如果宏的参数直接带有#
,则不会展开内层的嵌套宏
#include <stdio.h>
#define STR(x) #x
#define TO_STR(x) STR(x)
#define ADD(a, b) (a + b)
void main(void)
{
printf("%s\r\n", STR(ADD(3, 4)));
printf("%s\r\n", 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 <stdio.h>
#define STR(x) #x
#define TO_STR(x) STR(x)
#define DEF_VAR(a) var_##a
#define PARAM(x) param_##x
void main(void)
{
printf("%s\r\n", 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)