名稱空間
變體
操作

主函式

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

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

int main() { 主體 } (1)
int main(int argc, char* argv[]) { 主體 } (2)
int main(/* 實現定義 */) { 主體 } (3)
1) 一個獨立於環境提供引數執行的 main 函式。
2) 一個接受環境提供引數的 main 函式。
argcargv 的名稱是任意的,引數型別的表示也是任意的:int main(int ac, char** av) 同樣有效。
3) 一個實現定義的 main 函式型別,返回 int
C++ 標準建議實現定義的 main 函式將額外的(可選)引數放在 argv 之後。
argc - 一個非負值,表示從執行程式的環境中傳遞給程式的引數數量。
argv - 指向一個由 argc + 1 個指標組成的陣列的第一個元素的指標,其中最後一個是空指標,前一個(如果有)指向表示從執行環境傳遞給程式的引數的以空字元結尾的多位元組字串。如果 argv[0] 不是空指標(或者等價地,如果 argc > 0),它指向一個表示用於呼叫程式的名稱的字串,或一個空字串。
主體 - 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::exitstd::exit 隨後銷燬靜態物件並終止程式)。

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

1) 它不能在程式的任何地方被命名
a) 特別是,它不能被遞迴呼叫
b) 它的地址不能被獲取
c) 它不能在 typeid 表示式decltype 說明符(C++11 起)中使用
2) 它不能被預定義,也不能被過載:實際上,全域性名稱空間中的名稱 main 保留給函式(儘管它可以用作類、名稱空間、列舉以及非全域性名稱空間中任何實體的名稱,除非一個名為 main 的實體不能在任何名稱空間中用 C 語言連結宣告)。
3) 它不能被定義為刪除或(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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
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 日本語 中文(简体) 中文(繁體)