main 函式
程式必須包含一個名為 main 的全域函式,這是在託管環境中程式指定的啟動點。它必須具有以下形式之一:
int main() { body } |
(1) | ||||||||
int main(int argc, char* argv[]) { body } |
(2) | ||||||||
int main(/* implementation-defined */) { body } |
(3) | ||||||||
main 函式。main 函式。main 函式。main 函式將額外的(可選)參數放在 argv 之後。| argc | - | 非負值,表示從執行程式的環境傳遞給程式的參數數量。 |
| argv | - | 指向 argc + 1 個指標陣列的首元素指標,其中最後一個為空指標,若有的話,前幾個指標指向代表傳遞給程式之參數的以空字元結尾的多位元組字串。若 argv[0] 不是空指標(或者等價地,若 argc > 0),則它指向一個字串,該字串代表用於調用程式的名稱,或為空字串。 |
| body | - | main 函式的本體。 |
目錄 |
[編輯] 說明
main 函式在程式啟動時、於具有靜態儲存期的非區域物件初始化之後被呼叫。它是程式在託管環境(即具有作業系統的環境)中執行的指定進入點。獨立式程式(開機載入程式、作業系統核心等)的進入點則是實作定義的。
main 函式的雙參數形式允許從執行環境傳遞任意的多位元組字元字串(通常稱為「命令列參數」),指標 [argv[1], argv[argc - 1]] 指向這些字串中每個字串的首個字元。argv[0](若非空)是指向一個以空字元結尾的多位元組字串之首字元的指標,該字串代表用於調用程式本身的名稱(若執行環境不支援此功能,則為空字串 "")。這些字串是可以修改的,儘管這些修改不會傳回執行環境:例如,它們可以與 std::strtok 一起使用。argv 所指向陣列的大小至少為 argc + 1,且保證最後一個元素 argv[argc] 為空指標。
main 函式具有以下幾個特殊屬性:
main 末尾時的隱式 return)等同於先正常離開函式(此時會銷毀具有自動儲存期的物件並評估 main 的任何後置條件斷言(自 C++26 起)),然後以與 return 之引數相同的引數呼叫 std::exit(隨後 std::exit 會銷毀靜態物件並終止程式)。main 函式具有幾個限制(違反這些限制會導致程式格式錯誤):
main 是為函式保留的(儘管它可以用於命名類別、命名空間、列舉以及非全域命名空間中的任何實體,但名為 main 的實體不能在任何命名空間中以 C 語言連結宣告。constexpr(自 C++11 起)、consteval(自 C++20 起)、inline 或 static 宣告。|
4) main 函式的回傳類型不能被推導(不允許 auto main() {...})。 |
(C++14 起) |
| (自 C++20 起) |
[編輯] 附註
若 main 函式定義了函式 try 區塊,則由靜態物件解構函式(透過隱式的 std::exit 銷毀)所丟出的異常,不會被此區塊捕捉。
將作業系統命令列提供的參數轉換為 argv 所引用的多位元組字元陣列的方式,可能涉及實作定義的處理過程。
- 解析 C++ 命令列參數 (MSDN)
- Shell 簡介 (POSIX)
一種非常常見的 main() 實作定義形式包含第三個參數(除了 argc 和 argv 之外),其類型為 char**,指向一個指向執行環境變數的指標陣列。
[編輯] 範例
示範如何告知程式在哪裡尋找輸入以及在哪裡寫入結果。
可能的呼叫方式:./convert table_in.dat table_out.dat
#include <cstdlib> #include <iomanip> #include <iostream> int main(int argc, char *argv[]) { std::cout << "argc == " << argc << '\n'; for (int ndx{}; ndx != argc; ++ndx) std::cout << "argv[" << ndx << "] == " << std::quoted(argv[ndx]) << '\n'; std::cout << "argv[" << argc << "] == " << static_cast<void*>(argv[argc]) << '\n'; /* ... */ return argc == 3 ? EXIT_SUCCESS : EXIT_FAILURE; // optional return value }
可能輸出
argc == 3 argv[0] == "./convert" argv[1] == "table_in.dat" argv[2] == "table_out.dat" argv[3] == 0
[編輯] 參考資料
| 延伸內容 |
|---|
|
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯應用於之前的 C++ 標準。
| DR | 應用於 | 出版時的行為 | 正確的行為 |
|---|---|---|---|
| CWG 1003 | C++98 | main 的支援參數名稱限制過嚴 |
所有有效的參數 名稱皆得到支援 |
| CWG 1886 | C++98 | main 函式曾可以被宣告具有語言連結 |
禁止 |
| CWG 2479 | C++20 | main 函式曾可以被宣告為 consteval |
禁止 |
| CWG 2811 | C++98 | 在 N3214 之後是否使用 main 函式並不清楚 |
當其被命名時即視為被使用 |
[編輯] 參見
| C 文件 關於
main 函式 |