教科書、網路範例、舊專案中 main() 寫法五花八門:void main()、main()、int main()、int main(void)、int main(int argc, char *argv[])、甚至三參數版。本文梳理歷史演變、標準規範、編譯器擴展與最佳實務,終結選擇困擾。
| 年代/標準 | 主流寫法 | 關鍵變化 |
|---|---|---|
| K&R C (1978) | main() { printf("hello\n"); } | 隱式 int、無標頭、極致精簡 |
| K&R 2nd / ANSI C89 (1989) | int main(void) / main() | 倡導原型、int 可省略、() 標記過時 |
| C99 (1999) | int main(void) / int main(int argc, char *argv[]) | 強制 int、隱式聲明廢除、() 仍過時但保留 |
| C11/C17/C23 | 同上 | 維持 C99 規範 |
/*** 1. 無參數版 (C99/C11 標準) ***/
int main(void) { /* ... */ return 0; }
/*** 2. 命令列參數版 (C99/C11 標準) ***/
int main(int argc, char *argv[]) { /* ... */ return 0; }
/* 等價寫法:char **argv */
argc:參數個數(含程式名),≥ 1argv[0]:程式名稱/路徑;argv[argc] == NULLint ac, char **av),型別不可變| 寫法 | 狀態 | 問題 |
|---|---|---|
void main() | 非標準 | C90/C99 均不認可;C99 留「實作定義」後門,僅特定嵌入式編譯器支援;極差可移植性 |
main() / int main() | 過時 | () 非原型,C90 標記過時,C99 保留但不推薦;參數檢查失效 |
int main(int argc, char *argv[], char *envp[]) | 擴展 | UNIX/Linux/Windows MSVC 支援第三參數取環境變數;非標準,可移植性差;建議用 getenv() |
return EXIT_SUCCESS; | 標準等價 | <stdlib.h> 定義,語意更清晰;EXIT_FAILURE 表失敗 |
main 無 return → 未定義值返回 OSmain 結尾插入 return 0;(唯一允許隱式返回的函數)main 可能不返回,或由啟動代碼決定進入點名稱getch() / system("PAUSE")DOS/早期 Windows IDE (Turbo C, VC6) 執行後視窗即關,為觀察輸出而人為暫停:
getch():非標準 (conio.h),不回顯字元system("PAUSE"):標準 stdlib.h,但依賴 shell、有安全風險、效能差int main(int argc, char *argv[]) /* argc = argument count, argv = argument vector */ int main(int ac, char **av) /* 簡寫慣例,型別相同即合法 */
/*** 標準、可移植、無過時風險 ***/
int main(void) { /* ... */ return 0; }
int main(int argc, char *argv[]) { /* ... */ return 0; }
/*** 喜歡語意化 ***/
#include <stdlib.h>
int main(void) { /* ... */ return EXIT_SUCCESS; }
其餘寫法皆為歷史遺產、編譯器方言或錯誤示範,新代碼請勿使用。