理解原始碼如何轉換為可執行程式,是掌握建置系統、除錯符號、效能優化、跨平台建置的基礎。
原始檔 (.c) ──預處理──→ 擴充原始檔 (.i)
──編譯──→ 組合語言 (.s)
──組譯──→ 目標檔 (.o/.obj)
目標檔 (.o) + 靜態庫 (.a/.lib) + 動態庫 (.so/.dll)
──鏈接器──→ 可執行檔 (.exe / ELF)
// 標準 C (C99/C11) - 可移植寫法
int main(void) {
// ...
return 0; // 成功結束
}
// 或
int main(int argc, char* argv[]) {
// ...
return EXIT_SUCCESS; // 定義
}
| 作業系統 | 慣例 | 說明 |
|---|---|---|
| Unix/Linux/macOS | **強制** 回傳 `int` | Shell 透過 `$?` 取得,0=成功,非0=失敗碼 |
| Windows (MSVC) | 允許 `void main()` | 但回傳 `int` 更標準、可移植、利於腳本整合 |
| 嵌入式/無作業系統 | 視啟動程式碼而定 | 通常 `main` 不返回,或回傳值由啟動碼處理 |
最佳實務:永遠使用 `int main(void)` 或 `int main(int argc, char* argv[])` 並 `return 0;`/`EXIT_SUCCESS`。
// 三大注意要素
// 1. 含義區分:= (賦值) vs == (比較) vs === (不存在)
// 2. 優先級:高優先級先算 (如 * / % > + - > < <= > >= > == != > && > || > ? : > = += -=)
// 3. 結合性:同優先級方向 (大多左結合,= ?: 為右結合)
a = b = c = 5 + 3; // 右結合:c=8, b=8, a=8
// 等價於 a = (b = (c = (5 + 3)))
| 規則 | 說明 |
|---|---|
| 字元集 | 字母 (大小寫敏感)、數字、底線 `_` |
| 首字元 | **不能是數字** |
| 長度限制 | C89: 31 有效字元;C99: 63 有效字元 (編譯器實作可更長) |
| 保留字 | 關鍵字 (32 個)、標準庫識別子、雙底線開頭、底線+大寫開頭 |
// = 不是數學「等於」,是「賦值」
// 右結合:a = b = c = expr
// 副作用:賦值運算式有值 (賦值結果),可用於條件判斷
if ((fp = fopen("file.txt", "r")) != NULL) { ... }
// 復合賦值:a += b 等價 a = a + b (但 a 僅評估一次)
a[i++] += 1; // i 僅增 1 次
掌握編譯鏈接機制、main 回傳慣例、運算子語意、識別子規範,能讓你從「寫出能跑的代碼」進階到「理解程式如何在機器上運行」,是系統級開發者的必修內功。