プログラムは画面に文字を出力するだけでなく、実行が成功したか失敗したかをOSへ伝えています。
その合図がmain関数の戻り値です。
本記事では、return 0;は「成功」を表すという基本から、0以外の値の意味、終了コードの確認方法までを、C言語初心者の方にも分かりやすく丁寧に解説します。
C言語のmain関数の戻り値とは?
C言語のエントリポイントであるmain関数は必ずint型を返す関数です。
戻り値はプログラムの終了時にOSへ渡され、成功かエラーかを表現します。
ここでは「0は成功」「0以外はエラー」という約束事と、記述時の注意点を整理します。
return 0;の意味は「成功」
C言語ではmain関数からreturn 0;
すると「正常終了(成功)」を意味します。
この規約はCの世界で広く使われており、ツールやスクリプトはこの値を見て次の処理を判断します。
実は0
だけでなく、標準ライブラリstdlib.h
で定義されるEXIT_SUCCESS
も「成功」を意味します。
可搬性を重視する場合はEXIT_SUCCESSを使う書き方も有効です。
以下は代表的な値と意味の対応です。
戻り値の例 | 意味 | 備考 |
---|---|---|
0 | 成功(正常終了) | return 0; または return EXIT_SUCCESS; |
1 | 典型的な一般エラー | 具体的な理由はプログラム側の決め事 |
2 | コマンド引数や使い方の誤りなど | これもプログラム側の取り決め |
EXIT_SUCCESS | 成功 | #include <stdlib.h> が必要 |
EXIT_FAILURE | 失敗(異常終了) | #include <stdlib.h> が必要 |
0以外は「エラー」や「異常終了」
0以外の終了コードは「エラー」や「異常終了」を表します。
どの値がどのエラーかはプログラム設計で自由に決められます。
例えば1は「一般的なエラー」、2は「引数エラー」、3は「ファイル未発見」といった具合に割り当てると、ツールやバッチから原因を判別しやすくなります。
なお、UNIX系シェルでは終了コードは通常0〜255の範囲で扱われます(下位8ビットが意味を持ちます)。
Windowsのプロセス終了コードはより広い範囲を持ちますが、多くの自作Cプログラムでは0(成功)/非0(失敗)の区別だけ押さえれば十分です。
数値の具体的な意味は規格で固定されていません。
外部に公開するコマンドの場合は、READMEなどで終了コードの割り当て表を用意しておくと親切です。
mainの戻り値型(int)とreturn省略の注意
main関数は必ずint
を戻すように定義します。
典型的な宣言は次の2つです。
int main(void)
int main(int argc, char* argv[])
または等価な表現
void main() はCの規格に適合しない書き方です。
教材や古い実装由来の記述が残っていますが、避けてください。
また、C99以降ではmain関数の末尾の}
に到達した場合、暗黙にreturn 0;
したものと見なされます。
とはいえ、読みやすさと明確さのためにreturn 0;
を明示することをおすすめします。
終了コード(exit status)の基本
プログラムが終了するときに返す整数を終了コード(exit status)と呼びます。
この値はOSや呼び出し元のシェルに伝わり、後続の処理が参照します。
終了コードはOSやシェルに結果を伝える
Cプログラムがreturn 0;
で終わると、OSはそのプロセスが成功したと解釈します。
シェルは直前に実行したコマンドの終了コードを保持しており、パイプラインや条件分岐でこの値を使います。
POSIXシェルでは$?
、Windowsのcmd.exeでは%ERRORLEVEL%
がそれに相当します。
ツールやバッチ処理での使われ方
ビルドスクリプト、テスト自動化、ジョブスケジューラなどでは終了コードが成否の判定の基準になります。
例えば単体テストが1件でも失敗したらreturn 1;
で終わらせ、CI(継続的インテグレーション)に失敗を通知します。
データ処理のバッチでは、入力不足で2
、外部サービス障害で3
などと分けると、オペレーション側が原因を即座に把握できます。
書き方と簡単な例
ここでは基本形と、条件に応じて0または1を返す実例を示します。
サンプルには丁寧なコメントを付けています。
基本形 mainとreturn 0;
最小構成に近いプログラムです。
メッセージを表示して成功終了します。
// ファイル名: hello_return0.c
// 目的: 画面にメッセージを出し、成功(0)で終了するサンプル
#include <stdio.h> // printfを使うために必要
int main(void) {
// ここで何らかの処理を行う
printf("プログラムは正常に実行されました。\n");
// OSに「成功」を伝える
return 0;
}
プログラムは正常に実行されました。
条件で0と1を返す例
コマンドライン引数がok
なら成功(0)、それ以外は失敗(1)で終了する例です。
終了コードの確認に便利です。
// ファイル名: exit_sample.c
// 目的: 引数で成功/失敗を切り替え、終了コードを確認できるサンプル
// 使い方:
// 成功: ./exit_sample ok
// 失敗: ./exit_sample ng (ok以外は全て失敗扱い)
#include <stdio.h> // printf, puts
#include <string.h> // strcmp
int main(int argc, char* argv[]) {
if (argc >= 2 && strcmp(argv[1], "ok") == 0) {
puts("OK: 成功として終了します。");
return 0; // 成功
} else {
// 引数が足りない、またはok以外が指定された
printf("ERROR: 引数が不正です(指定値: %s)。\n",
(argc >= 2) ? argv[1] : "(なし)");
return 1; // 失敗
}
}
$ ./exit_sample ok
OK: 成功として終了します。
$ ./exit_sample ng
ERROR: 引数が不正です(指定値: ng)。
補足として、可搬性を重視したい場合はstdlib.h
のEXIT_SUCCESS
/EXIT_FAILURE
を使って次のように書けます。
#include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
/* ... */
return EXIT_SUCCESS; // または return EXIT_FAILURE;
終了コードの確認方法
実際にプログラムの終了コードを確認してみましょう。
環境ごとに確認方法が異なります。
Windowsでの確認方法(cmdの%ERRORLEVEL%)
Windowsのコマンドプロンプト(cmd.exe)では%ERRORLEVEL%に直前のコマンドの終了コードが入ります。
まずMinGWやTDM-GCC、MSYS2などのGCCでコンパイルし、実行して確認します。
:: コンパイル (例: MSYS2/MINGW64を使用)
gcc -O2 -o exit_sample.exe exit_sample.c
:: 成功ケース
exit_sample.exe ok
echo 終了コードは %ERRORLEVEL% です
:: 失敗ケース
exit_sample.exe ng
echo 終了コードは %ERRORLEVEL% です
OK: 成功として終了します。
終了コードは 0 です
ERROR: 引数が不正です(指定値: ng)。
終了コードは 1 です
補足(PowerShellの場合)
PowerShellでは$LASTEXITCODE
で確認します。
# コンパイルは同様(必要に応じて環境に合わせて実施)
.\exit_sample.exe ok
$LASTEXITCODE
.\exit_sample.exe ng
$LASTEXITCODE
OK: 成功として終了します。
0
ERROR: 引数が不正です(指定値: ng)。
1
macOS/Linuxでの確認方法($?)
UNIX系のシェル(bash/zsh等)では$?が直前コマンドの終了コードです。
ターミナルで次のように操作します。
# コンパイル(GCCが入っている前提)
gcc -O2 -o exit_sample exit_sample.c
# 成功ケース
./exit_sample ok
echo "終了コードは $?"
# 失敗ケース
./exit_sample ng
echo "終了コードは $?"
OK: 成功として終了します。
終了コードは 0
ERROR: 引数が不正です(指定値: ng)。
終了コードは 1
ワンポイント: シェルでは終了コードが0ならif条件を「成功」と見なす慣習があります。
そのため例えばif ./exit_sample ok; then ... fi
のように、0
が真、非0が偽という扱いになります。
まとめ
本記事では、C言語のmain関数の戻り値と終了コードについて解説しました。
return 0;は「成功」を表し、0以外は「エラー」を示す、という約束をまず押さえてください。
終了コードはOSやシェル、そしてスクリプトやCIツールが結果を判断するための大切な信号です。
C99以降はmainの末尾に達すると暗黙に0が返りますが、可読性と明確さのためにreturn 0;
を明示すると良いでしょう。
また、可搬性を意識するならEXIT_SUCCESS
/EXIT_FAILURE
の利用も検討してください。
「成功は0、失敗は非0」というルールを意識してコードを設計すると、ツール連携や運用がぐっと楽になります。