プリプロセッサ ステートメントは実行できません。それらは...まあ、前処理されています。これは、コンパイラが最初の単一パスを実行し、すべての前処理定義を解決することを意味します。前処理定義が 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;
}
特に、この関数にはC 命令が含まれfun
ていないことに注意してください。前処理の前に、2 つの前処理命令が含まれていましたが、次のとおりです。
- プロ処理したら消えた
fun
その時点では関数fun
やその他の C コードは存在しなかったため、実際には関数に属していませんでした。テキストとプリプロセッサ ステートメントのみ。
この作業は通常、C コンパイラによってサイレントかつ内部的に行われます。ただし、それらの多くには、前処理されたソース ファイルを保存するオプションがあります。上記のような結果が得られるはずです (ただし、#include<stdio.h>
多くの空白行と、ここでは単一の空白行として合成されたいくつかの C コードに展開されます)。
2 番目のケースは、OP の演習として残されています。