ご存知のように、私たちが勉強しているとき、教科書は次のように書かれています。プログラムの実行には4つのステップが必要です。
ソースファイルは、前処理段階->コンパイル段階->アセンブリ段階->リンク段階->実行可能ファイルを通過します
これは私の疑問と私が学んだことを説明するための通常の例です。
#include <stdio.h>
int main()
{
printf("hello");
return 0;
}
1.前処理段階。
プリプロセッサは、文字#で始まるコマンドに従って元のCプログラムを変更します。たとえば、hello.cの最初の行にある#include <stdio.h>コマンドは、プリプロセッサにシステムヘッダーファイルの内容を読み取り、それをプログラムテキストに直接挿入するように指示します。結果は、通常はファイル拡張子としてドットi。
#include <>システム標準の方法に従って、ファイルディレクトリを直接取得します。
#include ""現在のソースファイルディレクトリが見つからない場合は検索し、システム標準の方法に従って他のファイルディレクトリを検索します。
2.コンパイル段階。
コンパイラは、テキストファイルhello.iをアセンブリ言語プログラムを含むテキストファイルhello.sに変換します。
3.コンパイル段階。
アセンブラは、hello.sを機械語命令に変換し、これらの命令を再配置可能オブジェクトプログラムと呼ばれる形式にパックし、その結果をバイナリファイルであるオブジェクトファイルhello.oに保存します。
4.リンクフェーズ
helloプログラムはprintf関数を呼び出します。printf関数はprintf.oという名前の別のプリコンパイル済みファイルに存在し、このファイルは何らかの形式でhello.oにマージする必要があり、リンカーがここでのマージを担当します。
次の図は、上記の4つの段階をグラフで表したものです。
問題がある、
前処理段階では、#include <stdio.h>をロードした後、printf関数の宣言があります。次のリンク段階では、printfの実装場所を知る方法、そしてリンクします。??(ヘッダーファイルから関数プロトタイプの実装場所を知る方法)