C++ 程式從 `.h`/`.cpp` 文字檔變成二進位可執行檔,經歷:原始程式 → 預處理 → 編譯優化 → 目標檔 → 鏈接 → 可執行檔 六大階段。
預處理器(獨立程式)在真正編譯前處理原始碼,不進行語法解析,主要工作:
#define)#include、#ifdef 等)temp.h
#ifndef _HEADERNAME_H
#define _HEADERNAME_H
#include
inline void show(char *a) {
std::cout << a << std::endl; // annotation
}
#endif
main.cpp
#include "temp.h"
#define MACRO "This is a macro"
extern int i;
int main() {
std::cout << i << std::endl;
show(MACRO);
}
預處理後,#include 會將頭檔內容展開,MACRO 被替換,註解被移除,產生 `.i` 檔(或直接餵給編譯器)。
編譯器將預處理後的 `.i` 檔編譯為組合語言 `.s` 檔,並進行優化(死碼消除、內聯、循環展開等)。
組譯器將 `.s` 轉為機器碼目標檔 `.o` (Linux) 或 `.obj` (Windows),包含二進位指令、符號表、重定位資訊。
鏈接器將多個目標檔與庫檔(靜態 `.a`/.`lib`、動態 `.so`/.`dll`)合併,解析符號引用、修正地址、生成最終可執行檔(ELF/PE 格式)。
main.cpp → [預處理] → main.i → [編譯] → main.s → [組譯] → main.o
↓
temp.h → [預處理] → temp.i → [編譯] → temp.s → [組譯] → temp.o → [鏈接] → a.out
g++ -E 僅預處理,-S 產生組語,-c 僅編譯到目標檔。