预处理器语句不可执行。它们是……好吧,经过预处理。这意味着编译器将执行初始单遍并解析所有预处理定义。如果预处理定义位于 C 控制结构内,则无论 C 控制结构的含义如何,都将执行它。换句话说,从预处理器的角度来看,没有 C 代码。只是文本(和其他预处理器语句)。
在您的情况下,在这第一遍中:
#include<stdio.h> // File stdio.h is included/copied
#define s 10 // Preprocessor symbol s is defined as 10
fun() { // Copied literally
#undef s // Preprocessor symbol s is undefined
#define s 20 // Preprocessor symbol s is defined as 20
} // Copied literally
int main(){ // Copied literally
printf("%d\n",s); // Copied with s substituted, ie. printf("%d\n",20);
fun(); // Copied literally
printf("%d\n",s); // Copied with s substituted, ie. printf("%d\n",20);
return 0; // Copied literally
} // Copied literally
所以,真正被编译的输入是:
// Empty line originally corresponding to #include
// Empty line originally corresponding to #define
fun() {
// Empty line originally corresponding to #undef
// Empty line originally corresponding to #define
}
int main(){
printf("%d\n",20);
fun();
printf("%d\n",20);
return 0;
}
特别要注意,该fun
函数不包含任何C 指令。在预处理之前,它确实包含 2 个预处理指令,但是:
- 亲加工后消失
- 它们从未真正属于函数
fun
,因为那时没有函数fun
或任何其他 C 代码。只是文本和预处理器语句。
这项工作通常由 C 编译器在内部静默完成。但是,他们中的许多人都可以选择保存预处理的源文件。您应该获得与上述类似的结果(除了#include<stdio.h>
会扩展为许多空行和一些 C 代码,在这里我将其合成为单个空行)。
第二种情况留给 OP 作为练习。