这是一本书所做的练习。问题是这段代码的输出是什么。
此代码始终打印“N未定义”,但我不知道为什么。命令“#undef N”在函数f之后。那么,为什么输出总是“N未定义”?
#define N 100
void f(void);
int main(void)
{
f();
#ifdef N
#undef N
#endif
return 0;
}
void f(void)
{
#if defined(N)
printf("N is %d\n", N);
#else
printf("N is undefined\n");
#endif
}
本练习的目的是证明预处理器的控制流程与程序的控制流程完全分开。
#if
/ #undef
指令按照它们出现在程序文本中的顺序进行处理。它们在编译时只处理一次;在运行时无法重新考虑定义或取消定义预处理器变量的决定。
这就是为什么f
在#if
的#undef
/ main
线之前执行的事实是无关紧要的。您只能通过将f
移动到main
之前的文件位置来更改此程序的输出。
如果使用-E标志运行编译器(至少对于gcc),它将显示您实际编译的代码是什么。
您将看到预处理器不遵循代码执行 - 它按照它们在文件中出现的顺序执行其操作。
然后编译器获取生成的代码,f
只有一个调用printf
,其中N未定义。
C预处理器逐行完成您的代码。因此,由于函数调用,假设#undef
在函数f()
之后发生是错误的。相反,它发生在你定义函数f()
之前。
要理解这一点,您必须区分预处理器(逐行)和控制流(跟随函数调用)。
因为预处理器指令以“物理”顺序运行,所以一行一行。
想一想在实际编译之前执行某些操作,以这种方式清除代码,只使用编译器的纯C代码。