C 語言程序入口點:main 函數是執行起點,而非第一行代碼或第一個函數
經典選擇題:C 語言程序總是從 main() 函數開始執行。
選項分析
| 選項 | 內容 | 正確性 | 解析 |
| A | 書寫順序的第一個函數 | ❌ | 函數順序不影響執行,鏈接器查找 main 符號 |
| B | 書寫順序的第一條語句 | ❌ | 全局變量初始化、構造函數 (C++) 可能先於 main |
| C | 主函數 main | ✅ | C 標準規定:`main` 是程序啟動後第一個被調用的用戶函數 |
| D | 第一個被調用的函數 | ❌ | 運行時啟動代碼 (CRT) 先執行,再調用 main |
標準規定細節 (C11 §5.1.2.2)
- 程序啟動 → 運行時環境初始化 (CRT)
- 調用 `main` 函數
- `main` 返回 → 運行時清理 → 進程退出
main 函數標準簽名
int main(void) // 無參數
int main(int argc, char *argv[]) // 命令行參數
// 等價於
int main(int argc, char **argv)
- 返回 `int`:0/EXIT_SUCCESS 表示成功,非零表示失敗
- 參數:`argc` 參數個數 (含程序名),`argv` 參數字符串數組
啟動代碼 (CRT) 做了什麼?
- 堆/棧初始化
- 全局/靜態變量初始化 (`.data`、`.bba` 段)
- 命令行參數解析填充 `argc/argv`
- 環境變量表構建 (`environ`)
- 調用 `main`,獲取返回值
- 調用 `atexit` 註冊的清理函數
- 調用 `_exit` 終止進程
特殊情況
- 嵌入式/裸機:可能重定義入口為 `Reset_Handler`,經啟動代碼調用 `main`
- C++ 全局對象:構造函數在 `main` 前執行
- DLL/共享庫:入口為 `DllMain`,無 `main`