main 函式和命令列引數

所有 C++ 程式都必須有函 main 式。 如果您嘗試在沒有函式的情況下 main 編譯 C++ 程式,編譯器會引發錯誤。 (動態連結程式庫和 static 程式庫沒有函 main 式。函 main 式是原始程式碼開始執行的位置,但在程式進入 main 函式之前,沒有明確初始化運算式的所有 static 類別成員都會設定為零。 在 Microsoft C++ 中,全域 static 物件也會在進入 main 之前初始化。 數個限制適用于 main 不適用於任何其他 C++ 函式的函式。 函式 main

  • 無法多載(請參閱 函式 多載)。
  • 無法宣告為 inline
  • 無法宣告為 static
  • 無法取得其位址。
  • 無法從您的程式呼叫。

函式 main 簽章

main 式沒有宣告,因為它內建于語言中。 如果這樣做,的 main 宣告語法看起來會像這樣:

int main();
int main(int argc, char *argv[]);

如果未在 中 main 指定任何傳回值,編譯器會提供零的傳回值。

標準命令列引數

main 引數允許方便的命令列剖析引數。 argcargv 的類型是由語言定義。 名稱和 argcargv 是傳統的,但您可以將其命名為任何喜歡的名稱。

引數定義如下:

argc
整數,包含 中 argv 後續引數的計數。 argc 參數永遠會大於或等於 1。

argv
以 null 終止之字串的陣列,表示由程式的使用者所輸入的命令列引數。 依照慣例, argv[0] 是叫用程式的命令。 argv[1] 是第一個命令列引數。 命令列的最後一個引數是 ,且 argv[argc] 一律為 argv[argc - 1] Null。

如需如何隱藏命令列處理的資訊,請參閱 自訂 C++ 命令列處理

注意

依照慣例, argv[0] 是程式的檔案名。 不過,在 Windows 上,您可以使用 來繁衍進程 CreateProcess 。 如果您使用第一個和第二個引數 ( lpApplicationNamelpCommandLine ), argv[0] 可能不是可執行檔名稱。 您可以使用 GetModuleFileName 來擷取可執行檔名稱及其完整路徑。

Microsoft 特定擴充功能

下列各節說明 Microsoft 特定的行為。

函式 wmain_tmain

如果您將原始程式碼設計為使用 Unicode 寬 char 動作工具,您可以使用 Microsoft 特定的 wmain 進入點,這是 的寬 char 字元版本 main 。 以下是 的有效宣告語法 wmain

int wmain();
int wmain(int argc, wchar_t *argv[]);

您也可以使用 Microsoft 特定的 _tmain ,這是 中 tchar.h 定義的預處理器宏。 _tmain除非已定義,否則 _UNICODE 會解析為 main 。 在此情況下,_tmain 會解析成 wmain。 開頭的 _tmain 宏和其他宏 _t 對於必須針對窄型和寬 char 型動作工具集建置個別版本的程式碼很有用。 如需詳細資訊,請參閱 使用泛型文字對應

voidmain

做為 Microsoft 延伸模組, mainwmain 函式可以宣告為傳 void 回 (沒有傳回值)。 其他編譯器也提供此延伸模組,但不建議使用。 當未傳回值時 main ,它可用於對稱。

如果您宣告 main 或傳回 void ,則無法使用 語句,將程式碼傳回 exit 至父進程或作業系統 returnwmain 。 若要在 或 wmain 宣告為 voidmain 傳回程序 exit 代碼,您必須使用 函 exit 式。

envp命令列引數

mainwmain 簽章允許選擇性的 Microsoft 特定延伸模組存取環境變數。 此延伸模組也適用于 Windows 和 UNIX 系統的其他編譯器。 此名稱 envp 為傳統名稱,但您可以命名環境參數。 以下是包含環境參數之引數清單的有效宣告:

int main(int argc, char* argv[], char* envp[]);
int wmain(int argc, wchar_t* argv[], wchar_t* envp[]);

envp
選擇性 envp 參數是字串陣列,代表使用者環境中設定的變數。 這個陣列由 NULL 項目終止。 它可以宣告為 的指標 char 陣列( char *envp[] ) 或 做為 指標的 char 指標。 char **envp 如果您的程式使用 wmain 而非 main ,請使用 wchar_t 資料類型, char 而不是 。

傳遞至 mainwmain 的環境區塊是目前環境的「凍結」複本。 如果您稍後透過呼叫 putenv 或 來變更環境,則目前的環境(如 或 _wputenv 和 或 _wgetenv_wenviron 變數所傳回 getenv )將會變更,但 所 envp 指向的 _environ 區塊將不會變更。 如需有關如何隱藏環境處理的詳細資訊,請參閱 自訂 C++ 命令列處理 。 自 envp 變數與 C89 標準相容,但與 C++ 標準不相容。

的範例引數 main

下列範例示範如何使用 argcargvenvp 引數: main

// argument_definitions.cpp
// compile with: /EHsc
#include <iostream>
#include <string.h>

using namespace std;
int main( int argc, char *argv[], char *envp[] )
{
    bool numberLines = false;    // Default is no line numbers.

    // If /n is passed to the .exe, display numbered listing
    // of environment variables.
    if ( (argc == 2) && _stricmp( argv[1], "/n" ) == 0 )
         numberLines = true;

    // Walk through list of strings until a NULL is encountered.
    for ( int i = 0; envp[i] != NULL; ++i )
    {
        if ( numberLines )
            cout << i << ": "; // Prefix with numbers if /n specified
        cout << envp[i] << "\n";
    }
}

剖析 C++ 命令列引數

Microsoft C/C++ 程式碼所使用的命令列剖析規則是 Microsoft 特定的。 執行時間啟動程式碼會在解譯作業系統命令列上指定的引數時使用這些規則:

  • 引數會以空白或定位鍵的泛空白字元 (White Space) 進行分隔。

  • 第一個論點 ( argv[0] ) 是特別處理。 它代表程式名稱。 因為它必須是有效的路徑名稱,所以允許以雙引號 ( " ) 括住的部分。 輸出中未包含 argv[0] 雙引號標記。 以雙引號括住的部分,可防止將空格或製表 char 符動作器解譯為引數的結尾。 此清單中的後續規則不適用。

  • 以雙引號括住的字串會解譯為單一引數,其中可能包含空格 char 符動作。 有引號的字串可以內嵌到引數中。 插入號 ( ^ ) 無法辨識為逸出 char 動作者或分隔符號。 在引號字串中,一對雙引號會解譯為單一逸出雙引號標記。 如果命令列在找到結尾雙引號之前結束,則到目前為止讀取的所有 char 動作者都會輸出為最後一個引數。

  • 雙引號前面加上反斜線 ( \" ) 會解譯為常值雙引號 ( " )。

  • 反斜線會以字面方式解譯,除非它們緊接在雙引號前面。

  • 如果偶數反斜線後面接著雙引號,則會將一個反斜線 ( \ ) 放在陣列中 argv ,每對反斜線 (), 雙引號 ( \\" ) 會解譯為字串分隔符號。

  • 如果奇數的反斜線後面接著雙引號,則會在每個反斜線的陣列中 argv 放置一個反斜線 ()。 \\\ 雙引號會藉由重新 main 反斜線解譯為逸出序列,導致將常值雙引號 ( " ) 置於 argv 中。

命令列引數剖析的範例

下列程式示範如何傳遞命令列引數:

// command_line_arguments.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;
int main( int argc,      // Number of strings in array argv
          char *argv[],   // Array of command-line argument strings
          char *envp[] )  // Array of environment variable strings
{
    int count;

    // Display each command-line argument.
    cout << "\nCommand-line arguments:\n";
    for( count = 0; count < argc; count++ )
         cout << "  argv[" << count << "]   "
                << argv[count] << "\n";
}

剖析命令列的結果

下表顯示範例輸入和預期的輸出,示範上述清單中的規則。

命令列輸入 argv[1] argv[2] argv[3]
"abc" d e abc d e
a\\b d"e f"g h a\\b de fg h
a\\\"b c d a\"b c d
a\\\\"b c" d e a\\b c d e
a"b"" c d ab" c d

萬用字元展開

Microsoft 編譯器選擇性地可讓您使用 萬用字元 char 動作工具、問號 ( ? ) 和星號 ( * ),在命令列上指定檔案名和路徑引數。

命令列引數是由執行時間啟動程式碼中的內部常式所處理,預設不會將萬用字元擴充為字串陣列中的 argv 個別字串。 您可以在編譯器選項或 LINK 命令列中包含 setargv.obj/link 檔案 ( wsetargv.obj 檔案 for wmain ) 來啟用萬用字元擴充。

如需執行時間啟動連結器選項的詳細資訊,請參閱 連結選項

自訂 C++ 命令列處理

如果您的程式未採用命令列引數,您可以隱藏命令列處理常式,以節省少量的空間。 若要隱藏其使用方式, noarg.obj 請在編譯 /link 程式選項或 LINK 命令列中包含 檔案 (適用于 mainwmain )。

同樣地,如果您從未透過 envp 引數存取環境資料表,您可以隱藏內部環境處理常式。 若要隱藏其使用方式, noenv.obj 請在編譯 /link 程式選項或 LINK 命令列中包含 檔案 (適用于 mainwmain )。

您的程式可能會呼叫 spawn C 執行時間程式庫中的 或 exec 常式系列。 如果這樣做,您不應該隱藏環境處理常式,因為它用來將環境從父進程傳遞至子進程。

另請參閱

基本概念