作為 C/C++ 程式的入口點,main 的簽名直接關係到程式的可移植性、標準合規性與系統交互能力。初學者常見 main()、void main()、int main() 等多種寫法,究竟哪種才是標準?本文依據 ISO C (C99/C11) 與 ISO C++ (C++98/11/17) 標準文檔,給出權威答案。
| 語言標準 | 合法簽名 1 | 合法簽名 2 (帶參數) |
|---|---|---|
| C (C99/C11) | int main(void) | int main(int argc, char *argv[]) 或 int main(int argc, char **argv) |
| C++ (C++98 起) | int main() | int main(int argc, char *argv[]) |
核心規則:
int,用於向作業系統/啟動器報告退出狀態碼。void (int main(void));C++ 則省略參數表 (int main()) 即可。argc (argument count) 為參數個數,argv (argument vector) 為參數字串陣列指標;argv[0] 通常為程式路徑/名稱,argv[argc] 保證為 NULL。argc/argv 非強制,但為通用約定,建議保留。void main() / main() (隱式 int):舊式編譯器為兼容 K&R C 可能通過,現代編譯器 (GCC/Clang/MSVC 高警告級) 會報錯或警告,行為未定義。int 類型:違反 ABI 約定,導致啟動器讀取錯誤狀態碼。char *envp[]:POSIX 擴展,非標準,跨平台慎用。參數 (入口):作業系統/Shell 將命令列參數解析後,通過啟動器 (CRT) 傳遞給 main。應用層可解析選項、讀取配置、決定運行模式。
返回值 (出口):return 0 表示成功,非零表示失敗類型。Shell 可通過 $? (Bash) 或 %ERRORLEVEL% (Windows CMD) 獲取,實現腳本級錯誤處理流程控制。
args_demo.c#include <stdio.h>
int main(int argc, char *argv[]) {
printf("argc = %d\n", argc);
for (int i = 0; i < argc; ++i)
printf("argv[%d] = %s\n", i, argv[i]);
return 42; // 自定義退出碼
}
$ gcc args_demo.c -o args_demo $ ./args_demo hello world "test arg" argc = 4 argv[0] = ./args_demo argv[1] = hello argv[2] = world argv[3] = test arg $ echo $? 42
C:\> gcc args_demo.c -o args_demo.exe C:\> args_demo.exe hello world argc = 3 argv[0] = args_demo.exe argv[1] = hello argv[2] = world C:\> echo %ERRORLEVEL% 42
標準允許 main 被遞歸調用 (C++ 明確許可,C 隱式允許),但極不推薦:
int main(void) 或 int main(int argc, char *argv[])。int main() 或 int main(int argc, char *argv[])。-Wall -Wextra -pedantic / /W4) 並視警告為錯誤 (-Werror / /WX)。標準不是束縛,而是跨平台、跨編譯器、跨團隊協作的基石。從 main 寫起,踐行工程專業主義。