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
引數允許方便的命令列剖析引數。 argc
和 argv
的類型是由語言定義。 名稱和 argc
argv
是傳統的,但您可以將其命名為任何喜歡的名稱。
引數定義如下:
argc
整數,包含 中 argv 後續引數的計數。 argc 參數永遠會大於或等於 1。
argv
以 null 終止之字串的陣列,表示由程式的使用者所輸入的命令列引數。 依照慣例, argv[0]
是叫用程式的命令。 argv[1]
是第一個命令列引數。 命令列的最後一個引數是 ,且 argv[argc]
一律為 argv[argc - 1]
Null。
如需如何隱藏命令列處理的資訊,請參閱 自訂 C++ 命令列處理 。
注意
依照慣例, argv[0]
是程式的檔案名。 不過,在 Windows 上,您可以使用 來繁衍進程 CreateProcess
。 如果您使用第一個和第二個引數 ( lpApplicationName
和 lpCommandLine
), 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 型動作工具集建置個別版本的程式碼很有用。 如需詳細資訊,請參閱 使用泛型文字對應 。
從 void
main
做為 Microsoft 延伸模組, main
和 wmain
函式可以宣告為傳 void
回 (沒有傳回值)。 其他編譯器也提供此延伸模組,但不建議使用。 當未傳回值時 main
,它可用於對稱。
如果您宣告 main
或傳回 void
,則無法使用 語句,將程式碼傳回 exit 至父進程或作業系統 return
wmain
。 若要在 或 wmain
宣告為 void
時 main
傳回程序 exit 代碼,您必須使用 函 exit
式。
envp
命令列引數
main
或 wmain
簽章允許選擇性的 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
而不是 。
傳遞至 main
且 wmain
的環境區塊是目前環境的「凍結」複本。 如果您稍後透過呼叫 putenv
或 來變更環境,則目前的環境(如 或 _wputenv
和 或 _wgetenv
_wenviron
變數所傳回 getenv
)將會變更,但 所 envp
指向的 _environ
區塊將不會變更。 如需有關如何隱藏環境處理的詳細資訊,請參閱 自訂 C++ 命令列處理 。 自 envp
變數與 C89 標準相容,但與 C++ 標準不相容。
的範例引數 main
下列範例示範如何使用 argc
、 argv
和 envp
引數: 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
命令列中包含 檔案 (適用于 main
和 wmain
)。
同樣地,如果您從未透過 envp
引數存取環境資料表,您可以隱藏內部環境處理常式。 若要隱藏其使用方式, noenv.obj
請在編譯 /link
程式選項或 LINK
命令列中包含 檔案 (適用于 main
和 wmain
)。
您的程式可能會呼叫 spawn
C 執行時間程式庫中的 或 exec
常式系列。 如果這樣做,您不應該隱藏環境處理常式,因為它用來將環境從父進程傳遞至子進程。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應