命名空間
變體
動作

main 函式

出自 cppreference.com
< cpp‎ | language
 
 
C++ 語言
一般主題
流程控制
條件執行陳述式
if
疊代陳述式 (迴圈)
for
範圍 for (C++11)
跳躍陳述式
函式
函式宣告
Lambda 函式運算式
inline 指定符
動態例外規範 (直到 C++17*)
noexcept 指定符 (C++11)
例外
命名空間
型別
指定符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
儲存期指定符
初始化
 
 

程式必須包含一個名為 main 的全域函式,這是在託管環境中程式指定的啟動點。它必須具有以下形式之一:

int main() { body } (1)
int main(int argc, char* argv[]) { body } (2)
int main(/* implementation-defined */) { body } (3)
1) 獨立於環境提供之參數運作的 main 函式。
2) 接受環境提供之參數的 main 函式。
argcargv 的名稱是任意的,參數類型的表示方式亦然:int main(int ac, char** av) 同樣有效。
3) 實作定義類型且回傳 intmain 函式。
C++ 標準建議實作定義的 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 函式具有以下幾個特殊屬性:

1) main 函式的本體不需要包含 return 陳述式:若程式執行流到達 main 的末尾而未遇到 return 陳述式,其效果等同於執行 return 0;
2) return 的執行(或到達 main 末尾時的隱式 return)等同於先正常離開函式(此時會銷毀具有自動儲存期的物件並評估 main 的任何後置條件斷言(自 C++26 起)),然後以與 return 之引數相同的引數呼叫 std::exit(隨後 std::exit 會銷毀靜態物件並終止程式)。

main 函式具有幾個限制(違反這些限制會導致程式格式錯誤):

1) 在程式中的任何位置都不能對其命名
a) 特別是,它不能被遞迴呼叫
b) 不能取得它的位址
c) 不能在 typeid 表達式decltype 指定符(自 C++11 起)中使用
2) 它不能被預先定義且不能被重載:實際上,全域命名空間中的名稱 main 是為函式保留的(儘管它可以用於命名類別、命名空間、列舉以及非全域命名空間中的任何實體,但名為 main 的實體不能在任何命名空間中以 C 語言連結宣告。
3) 它不能被定義為 deleted 或(自 C++11 起)以任何語言連結、constexpr(自 C++11 起)consteval(自 C++20 起)inlinestatic 宣告。
4) main 函式的回傳類型不能被推導(不允許 auto main() {...})。
(C++14 起)
5) main 函式不能是協程
6) main 函式不能附加到具名的模組
(自 C++20 起)

[編輯] 附註

main 函式定義了函式 try 區塊,則由靜態物件解構函式(透過隱式的 std::exit 銷毀)所丟出的異常,不會被此區塊捕捉

將作業系統命令列提供的參數轉換為 argv 所引用的多位元組字元陣列的方式,可能涉及實作定義的處理過程。

一種非常常見的 main() 實作定義形式包含第三個參數(除了 argcargv 之外),其類型為 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++23 標準 (ISO/IEC 14882:2024)
  • 6.9.3.1 main 函式 [basic.start.main]

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯應用於之前的 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 函式
English Deutsch 日本語 中文(简体) 中文(繁體)