我刚刚学习了一个教程,该教程涉及执行CPP宏以在程序中实现调试系统。宏的一个很棒的行为是递归的,这样就可以将宏放在另一个宏中,如下所示:
#define MACRO1 "World"
#define MACRO2 printf("Hello %s\n",MACRO1);
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[]){
MACRO2
return 0;
}
输出:Hello World
以下似乎也有效:
#define MACRO2 printf("Hello %s\n",MACRO1);
#define MACRO1 "World"
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[]){
MACRO2
return 0;
}
所以只是为了理解,CPP是否首先读取所有#define X
以生成已声明宏的列表,然后替换其他宏中的宏,避免使用&#34;鸡蛋和鸡蛋&#34;关于预处理的问题?
我认为这是有道理的,因为预处理是一次性过程(在编译期间),而不是实时发生。因此,在代码中定义宏的位置并不重要,但实际上如果定义了宏。
拥有3000行代码并且仅在定义代码中使用的宏的最后一行中有效吗?
提前谢谢!
答案 0 :(得分:1)
实际发生的是递归替换仅在使用宏时发生,而不是在使用宏时发生。
所以在
#define MACRO2 printf("Hello %s\n",MACRO1);
预处理器只记得MACRO2
扩展为7个令牌printf
,(
,"Hello %s\n"
,,
,MACRO1
,{{ 1}}和)
。在这一点上,如果这些令牌中的任何一个是宏,它并不关心。
在;
所在的位置
main
预处理器将宏扩展为这七个令牌,然后检查令牌流是否包含可再次扩展的任何宏。它注意到MACRO2
并替换了令牌MACRO1
。此时它再次检查,但没有更多的宏用于扩展。
如果您尝试使用宏之前"World"
d。