一個 C/C++ 程式從編寫到執行,經歷四個主要階段:預處理 → 編譯 → 組譯 → 連結。理解各階段作業內容,對除錯、優化、跨平台開發至關重要。

處理以 # 開頭的指令,產生 .i (或 .ii) 擴充後的原始碼。
| 指令 | 功能 |
|---|---|
#define | 定義巨集/常數,支援參數化巨集 |
#include | 展開標頭檔內容(遞迴處理) |
#undef | 取消巨集定義 |
#if/#ifdef/#ifndef/#elif/#else/#endif | 條件編譯 |
#error | 強制產生編譯錯誤訊息 |
#pragma | 編譯器專屬指示 |
#line | 修改 __LINE__/__FILE__ 預定義巨集 |
#define MAX 100 遇 MAX 直接換成 100#include 會遞迴展開,需防護重複包含(#pragma once 或防護巨集)將預處理後的 .i 檔編譯為組合語言檔 .s (或 .asm)。此階段進行:
將 .s 組譯為目的檔 .o (Windows 為 .obj),包含機器碼但符號位址未解析。
將一或多個 .obj、靜態函式庫 .lib/.a、動態函式庫 .dll/.so 連結為最終執行檔。
# GCC/Clang gcc -E main.c -o main.i # 僅預處理 gcc -S main.i -o main.s # 僅編譯至組語 gcc -c main.s -o main.o # 僅組譯 gcc main.o -o main # 僅連結 gcc main.c -o main # 一鍵完成 # MSVC cl /E main.c > main.i # 預處理輸出至標準輸出 cl /c main.c # 編譯+組譯產生 .obj link main.obj # 連結
| 指令 | 用途 |
|---|---|
#pragma once | 標頭檔防護,替代傳統防護巨集 |
#pragma message("text") | 編譯時輸出訊息,除錯巨集定義用 |
#pragma warning(disable:4996) | 關閉特定警告 |
#pragma pack(n) | 設定結構體對齊邊界 (n=1,2,4,8,16) |
#pragma comment(lib, "name.lib") | 連結時自動引入函式庫 (MSVC) |
#pragma code_seg("section") | 指定函數程式碼段 (驅動開發用) |
#pragma hdrstop | 預編譯標頭截止點 |
-E//E) 確認巨集展開、條件編譯結果-S//Fa) 分析最佳化效果、函數呼叫慣例nm/dumpbin /symbols 檢視目的檔符號表