main
関数とコマンド ライン引数
すべての C++ プログラムは、main
関数を持つ必要があります。 main
関数を使用せずに C++ プログラムをコンパイルしようとすると、コンパイラでエラーが発生します (ダイナミック リンク ライブラリと static ライブラリには main
関数がありません)。この main
関数はソース コードの実行を開始する場所ですが、プログラムが関数に入る main
前に、明示的な初期化子を持たないすべての static クラス メンバーが 0 に設定されます。 Microsoft C++ では、グローバルな static オブジェクトも main
に入る前に初期化されます。 他の C++ の関数には適用されない複数の制限が main
関数に適用されます。 main
関数は、次のことを行います。
- オーバーロードすることはできません (「関数のオーバーロード」を参照してください)。
inline
として宣言することはできません。static
として宣言することはできません。- そのアドレスを取得することはできません。
- プログラムから呼び出すことはできません。
main
関数シグネチャ
main
関数は、言語に組み込まれているため、宣言を持ちません。 これが行われた場合、main
の宣言構文は次のようになります。
int main();
int main(int argc, char *argv[]);
main
に戻り値が指定されていない場合、コンパイラは戻り値として 0 を指定します。
標準コマンドライン引数
main
の引数を使用すると、コマンドラインで引数を簡単に解析できます。 argc
と argv
の型は、言語によって定義されています。 argc
および argv
という名前は従来と同じですが、自由に名前を付けることができます。
引数の定義は、次のとおりです。
argc
これに続いて argv で渡される引数の数を格納した整数。 argc パラメーターは、必ず 1 以上になります。
argv
プログラムのユーザーが入力したコマンド ライン引数を表す、null で終了する文字列配列。 慣例により、argv[0]
は、プログラムが起動されるコマンドです。 argv[1]
は、最初のコマンド ライン引数です。 コマンドラインからの最後の引数は argv[argc - 1]
であり、argv[argc]
は常に NULL です。
コマンドライン処理を抑制する方法の詳細については、「C++ コマンドライン処理のカスタマイズ」を参照してください。
Note
規則により、argv[0]
はプログラムのファイル名です。 ただし、Windows では、CreateProcess
を使用してプロセスを生成することができます。 1 番目と 2 番目の引数 (lpApplicationName
と lpCommandLine
) の両方を使用する場合は、argv[0]
を実行可能ファイルの名前にすることはできません。 GetModuleFileName
を使用すると、実行可能ファイル名とその完全修飾パスを取得できます。
Microsoft 固有の拡張機能
以下のセクションでは、Microsoft 固有の動作について説明します。
wmain
関数と _tmain
マクロ
Unicode ワイド文字を使用するようにソース コードを設計する場合は、Microsoft 固有の wmain
エントリ ポイントを使用できます。これは、main
のワイド文字バージョンです。charchar 次に、wmain
の有効な宣言構文を示します。
int wmain();
int wmain(int argc, wchar_t *argv[]);
「tchar.h
」で定義されているプリプロセッサ マクロである、Microsoft 固有の _tmain
を使用することもできます。 _UNICODE
が定義されていない場合、_tmain
は main
に解決されます。 定義されている場合、_tmain
は wmain
に解決されます。 _t
で始まる _tmain
マクロとその他のマクロは、ナローとワイドの両方の文字セットに個別のバージョンを構築する必要があるコードに便利です。char 詳細については、「汎用テキスト マップの使用」を参照してください。
main から void
を返す
Microsoft 拡張機能として、main
および wmain
関数を void
を返す (戻り値なし) ように宣言できます。 この拡張機能は、他のいくつかのコンパイラでも使用できますが、その使用は推奨されていません。 main
が値を返さない場合、対称性のために使用できます。
void
を返すように main
または wmain
を宣言した場合、return
ステートメントを使用して親プロセスまたはオペレーティング システムに exit コードを返すことはできません。 main
または wmain
が void
として宣言されているときに 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
) へのポインターへのポインターとして宣言できます。 プログラムが main
ではなく wmain
を使用している場合は、char
の代わりに wchar_t
データ型を使用します。
main
および wmain
に渡される環境ブロックは、現在の環境の "固定の" コピーです。 その後 putenv
または _wputenv
の呼び出しによって環境を変更する場合、現在の環境 (getenv
または _wgetenv
および _environ
または _wenviron
変数が返す) は変わりますが、envp
が指すブロックは変わりません。 環境処理を抑制する方法の詳細については、「C++ コマンドライン処理のカスタマイズ」を参照してください。 envp
引数は、C89 標準と互換性がありますが、C++ 標準には対応していません。
main
への引数の例
次の例は、main
への argc
、argv
、および envp
引数の使用方法を示しています。
// 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 固有のものです。 ランタイム スタートアップ コードは、オペレーティング システムのコマンド ラインで指定された引数を解釈する場合に、次のルールを使用します。
引数は、空白 (スペースまたはタブ) で区切ります。
最初の引数 (
argv[0]
) は、特別に処理されます。 それはプログラム名を表します。 有効なパス名である必要があるため、一部分を二重引用符 ("
) で囲むことが許可されます。 二重引用符は、argv[0]
の出力には含まれません。 二重引用符で囲まれた部分については、スペース文字またはタブ文字が引数の末尾として解釈されません。char この一覧で後に示す規則は適用されません。二重引用符で囲まれた文字列は、空白文字が含まれているかどうかにかかわらず、1 つの引数として解釈されます。char 二重引用符で囲んだ文字列を引数に埋め込むこともできます。 キャレット (
^
) は、エスケープ文字または区切り記号として認識されません。char 引用符で囲まれた文字列内では、二重引用符のペアは単一のエスケープされた二重引用符として解釈されます。 終了の二重引用符が検出される前にコマンド ラインが終了した場合は、それまでに読み取られたすべての文字が最後の引数として出力されます。char円記号を前に付けた二重引用符 (
\"
) は、リテラルの二重引用符文字 ("
) として解釈されます。二重引用符の直前にある円記号以外は、円記号として文字どおり解釈されます。
二重引用符の直前に円記号が偶数個あると、円記号のペア (
\\
) ごとに 1 個の円記号 (\
) がargv
配列に配置されます。この場合、二重引用符 ("
) は文字列の区切り記号として解釈されます。奇数個の円記号の後に二重引用符がある場合は、円記号のペア (
\\
) ごとに 1 個の円記号 (\
) がargv
配列に配置されます。 二重引用符は残りのバックスラッシュによってエスケープ シーケンスとして解釈され、リテラルの二重引用符 ("
) がargv
に配置されます。main
コマンドライン引数の解析の例
次のプログラムは、コマンド ライン引数がどのように受け渡されるかを示します。
// 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
コンパイラ オプションまたは LINK
コマンド ラインで setargv.obj
ファイル (wmain
の場合は wsetargv.obj
ファイル) を含めることで、ワイルドカードの展開を有効にすることができます。
ランタイムのスタートアップ リンカー オプションの詳細については、「リンク オプション」を参照してください。
C++ のコマンド ライン処理のカスタマイズ
プログラムがコマンド ライン引数を受け取らない場合は、コマンド ライン処理ルーチンを抑制して領域を少し節約できます。 その使用を抑制するには、 noarg.obj
ファイルを (main
、wmain
どちらの場合でも) /link
コンパイラ オプションまたは LINK
コマンド ラインに含めます。
同様に、 envp
引数を使用して環境のテーブルにアクセスしない場合は、内部の環境処理ルーチンを抑制できます。 その使用を抑制するには、 noenv.obj
ファイルを (main
、wmain
どちらの場合でも) /link
コンパイラ オプションまたは LINK
コマンド ラインに含めます。
プログラムによって、C ランタイム ライブラリの spawn
または exec
ファミリのルーチンが呼び出されることがあります。 その場合は、親プロセスから子プロセスに環境を渡すために環境処理ルーチンが使用されるため、抑制しないでください。
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示