6日でできる 新C言語入門|main関数がOSへ返す値とは

プログラムは、終わるときに結果をOSへ返している。
main関数の戻り値を理解して、正常終了とエラー終了を正しく伝えられるようになろう。

C言語のプログラムは、基本的にmain関数から実行が始まります。学習用のサンプルプログラムでも、次のような形をよく見かけます。

int main(void) {
    return 0;
}

この最後に書かれているreturn 0;は、ただプログラムを終わらせるためだけのものではありません。main関数が返す値は、プログラムの実行結果としてOSへ渡されます。

この値は、終了コード、終了ステータス、終了状態などと呼ばれることがあります。

一般的には、main関数が0を返すと正常終了を表します。一方で、0以外の値を返すと、何らかのエラーや異常終了を表すことが多いです。

たとえば、入力値が正しくなかった、ファイルを開けなかった、必要なデータが見つからなかった、といった場合に0以外の値を返すことで、OSや他のプログラムに失敗を知らせることができます。

この記事では、main関数の戻り値がどのような意味を持つのか、return 0;とreturn 1;の違い、終了コードを確認する方法、エラー処理での使い方まで、サンプルプログラムを使いながらやさしく解説していきます。

main関数も戻り値を持つ関数

main関数は、C言語プログラムの実行開始地点です。そして、多くの場合、次のようにint型で定義します。

int main(void) {
    return 0;
}

この形を見ると、main関数もほかの関数と同じように、戻り値を持つ関数であることが分かります。

部分意味
intmain関数が整数値を返すことを表す
mainプログラムの実行開始地点となる関数名
void引数を受け取らないことを表す
return 0;OSへ0を返して終了する

通常の自作関数では、戻り値はその関数を呼び出した関数へ返されます。

たとえば、計算用の関数なら、計算結果をmain関数へ返すことがあります。

一方で、main関数の戻り値は、プログラム全体の実行結果としてOSへ返されます。つまり、main関数のreturnは、CプログラムからOSへの終了報告のような役割を持っています。

return 0;は正常終了を表す

C言語の基本的なプログラムでは、最後にreturn 0;を書くことがよくあります。

return 0;

この0は、プログラムが正常に終了したことを表す値として広く使われます。

たとえば、計算が予定どおりに完了した、入力処理に問題がなかった、エラーが起きなかった、という場合にはreturn 0;で終了します。

main関数の戻り値一般的な意味
0正常終了
0以外エラー終了、異常終了、失敗など

0以外の値の意味は、プログラム側である程度決めることができます。

たとえば、1は入力エラー、2はファイルエラー、3はデータ不足のように、エラーの種類ごとに値を分けることもできます。

ただし、最初の段階では、0は正常終了、0以外は何らかの異常終了を表すと覚えておくと分かりやすいです。

図:main関数の戻り値はOSへ渡される

この図から分かること

この図から分かるのは、main関数の戻り値がプログラムの外側へ渡されるということです。

通常の関数の戻り値は、その関数を呼び出した処理へ返されます。一方、main関数の戻り値は、プログラムの実行結果としてOSへ返されます。そのため、return 0;は、プログラムが正常に終わったことをOSへ知らせる役割を持ちます。

正常終了を表すプログラム

次のプログラムでは、商品の合計金額を計算し、問題なく処理が完了したことをreturn 0;で表します。

プロジェクト/ファイル名: Lesson41_1/main.c

#include <stdio.h>

int main(void) {
    int price = 900;
    int count = 4;
    int total;

    // 商品の合計金額を計算する
    total = price * count;

    printf("合計金額は %d 円です。\n", total);
    printf("処理は正常に完了しました。\n");

    // 正常終了をOSへ伝える
    return 0;
}

実行結果

合計金額は 3600 円です。
処理は正常に完了しました。

このプログラムでは、priceとcountを使って合計金額を計算しています。

処理が問題なく完了したため、最後にreturn 0;を実行しています。

return 0;

この0が、プログラムの終了コードとしてOSへ返されます。

画面にはprintfでメッセージが表示されますが、それとは別に、OS側にはmain関数の戻り値が渡されます。

画面表示と終了コードは別のもの

printfで表示されるメッセージと、main関数の戻り値は別のものです。

printf("処理は正常に完了しました。\n");
return 0;

printfは、ユーザーに向けて画面へメッセージを表示します。
return 0;は、OSへプログラムの終了結果を伝えます。

処理相手役割
printfユーザー画面にメッセージを表示する
return 0;OS正常終了を終了コードで伝える

この違いはとても大切です。

たとえば、画面にエラーメッセージを表示していても、最後にreturn 0;を返すと、OSから見ると正常終了として扱われる場合があります。

反対に、画面には何も表示しなくても、return 1;を返せば、OSには異常終了として伝わります。

return 1;などの0以外は異常終了を表す

プログラムの途中でエラーが起きた場合や、処理を続けられない場合には、main関数から0以外の値を返します。

return 1;

一般的に、0以外の値はエラー終了や異常終了を表すために使われます。

ただし、0以外の値が具体的に何を意味するかは、プログラムの設計によって変わります。小さな学習用プログラムでは、1を一般的なエラーとして使うだけでも十分です。

戻り値使い方の例
0正常に処理が完了した
1入力値が不正だった
2ファイルを開けなかった
3必要なデータが見つからなかった

このように終了コードを分けると、プログラムを実行した側が、どのような理由で失敗したのかを判断しやすくなります。

エラー終了を表すプログラム

次のプログラムでは、購入個数が0以下の場合にエラーとして扱い、return 1;で終了します。

プロジェクト/ファイル名: Lesson41_2/main.c

#include <stdio.h>

int main(void) {
    int count;
    int price = 700;
    int total;

    printf("購入個数を入力してください: ");
    scanf("%d", &count);

    // 個数が0以下の場合はエラーとして終了する
    if (count <= 0) {
        printf("エラー: 個数は1以上で入力してください。\n");

        // 異常終了をOSへ伝える
        return 1;
    }

    // 正しい個数なら合計金額を計算する
    total = price * count;

    printf("合計金額は %d 円です。\n", total);
    printf("処理は正常に完了しました。\n");

    // 正常終了をOSへ伝える
    return 0;
}

実行結果

購入個数を入力してください: 0
エラー: 個数は1以上で入力してください。

このプログラムでは、まず購入個数を入力します。

scanf("%d", &count);

その後、countの値を確認します。

if (count <= 0)

countが0以下の場合、正しい合計金額を計算できないため、エラーメッセージを表示してreturn 1;で終了します。

return 1;

この時点でmain関数は終了するため、その下にある合計金額の計算は実行されません。

一方、1以上の個数が入力された場合は、合計金額を計算し、最後にreturn 0;で正常終了します。

Visual Studioでscanfを使う場合、環境設定によって警告が表示されることがあります。学習用として動作確認する場合は、必要に応じてSDLチェックの設定も確認しておきましょう。

returnはmain関数をそこで終了させる

returnが実行されると、その関数はそこで終了します。これはmain関数でも同じです。

次の部分を見てみましょう。

if (count <= 0) {
    printf("エラー: 個数は1以上で入力してください。\n");
    return 1;
}

countが0以下の場合、return 1;が実行されます。すると、main関数の処理はその場で終了し、プログラムは終了コード1をOSへ返します。

そのため、エラーを見つけた時点で早めに処理を終えることができます。

このような書き方は、エラー処理でよく使われます。不正な条件を先にチェックし、問題があればエラーコードを返して終了することで、その後の処理を安全に進められます。

図:正常終了と異常終了で戻り値が変わる

この図から分かること

この図から分かるのは、プログラムの終了時に返す値によって、OSへ伝わる意味が変わるということです。

処理が正しく完了した場合はreturn 0;で正常終了を伝えます。入力値が不正な場合など、処理を続けられないときはreturn 1;などの0以外の値を返して、異常終了を伝えます。

終了コードは他の処理から確認できる

main関数の戻り値は、OSだけでなく、シェルスクリプトやバッチファイルなどの別の処理から確認できます。

たとえば、あるCプログラムを実行したあと、その終了コードを確認することで、次の処理を変えられます。

終了コード次の処理の例
0次の処理へ進む
1エラーメッセージを表示する
2ファイルの存在を確認する
3入力データを確認する

このように、終了コードはプログラム同士の連携にも使われます。

小さな学習用プログラムでは、画面に結果を表示するだけでも十分に見えるかもしれません。しかし、実際の開発では、プログラムが成功したのか失敗したのかを外部から判断できることが大切です。

LinuxやmacOSで終了コードを確認する

LinuxやmacOSなどのUnix系環境では、プログラムを実行したあと、次のコマンドで直前の終了コードを確認できます。

echo $?

たとえば、プログラムがreturn 0;で終了した場合は、0が表示されます。return 1;で終了した場合は、1が表示されます。

実行の流れは、次のようになります。

./main
echo $?

1行目でプログラムを実行し、2行目で直前に実行したプログラムの終了コードを確認します。

Windowsで終了コードを確認する

Windowsのコマンドプロンプトでは、直前に実行したプログラムの終了コードを次のように確認できます。

echo %ERRORLEVEL%

作成したプログラムを実行したあとにこのコマンドを入力すると、main関数が返した値を確認できます。

PowerShellでは確認方法が異なる場合がありますが、基本的な考え方は同じです。プログラムがOSへ返した終了コードを、外側の環境から確認できます。

図:終了コードはコマンドラインから確認できる

この図から分かること

この図から分かるのは、main関数の戻り値がOSに渡され、その値をコマンドラインから確認できるということです。

LinuxやmacOSではecho $?、Windowsのコマンドプロンプトではecho %ERRORLEVEL%を使うことで、直前に実行したプログラムの終了コードを確認できます。これにより、プログラムが正常終了したのか、エラー終了したのかを外部から判断できます。

終了コードを使うと次の処理を分岐できる

終了コードは、ただ確認するだけでなく、次の処理を決めるためにも使われます。

たとえば、あるプログラムが成功したら次の処理へ進み、失敗したらエラー対応を行う、といった使い方ができます。

状態終了コード次の処理
正常終了0次のプログラムを実行する
入力エラー1入力内容を確認する
ファイルエラー2ファイルの存在を確認する

このように終了コードを使うと、Cプログラムを単体で動かすだけでなく、他のプログラムやスクリプトと連携させやすくなります。

C言語の学習では、まずreturn 0;とreturn 1;の違いを理解するところから始めれば十分です。慣れてきたら、エラーの種類ごとに戻り値を分ける設計にも挑戦できます。

main関数の戻り値で注意したいこと

main関数の戻り値については、次の点を意識しておくと分かりやすくなります。

正常終了ならreturn 0;を使う

処理が予定どおりに完了した場合は、return 0;を使うのが一般的です。

return 0;

エラーがあるなら0以外を返す

入力値が不正だった場合や、処理を続けられない場合は、return 1;などの0以外の値を返すことで、異常終了を表せます。

return 1;

表示メッセージだけではOSに状態は伝わらない

エラーと表示しても、戻り値が0なら、OS側では正常終了として扱われることがあります。

printf("エラーが発生しました。\n");
return 0;

この場合、画面上はエラーに見えますが、終了コードは0です。エラーとしてOSへ伝えたい場合は、0以外を返す必要があります。

学習用でもreturn 0;を書く習慣をつける

C言語では、main関数の最後でreturn 0;を書く形に慣れておくと、プログラムの終了を明確に表せます。

main関数の戻り値を意識するとプログラムの状態を伝えられる

main関数の戻り値は、プログラムが終了するときにOSへ返される値です。多くの場合、0は正常終了、0以外は異常終了を表すために使われます。

画面に表示するメッセージはユーザーに向けた情報ですが、returnで返す値はOSや他のプログラムに向けた情報です。この2つを分けて考えると、main関数の戻り値の役割が分かりやすくなります。

正常に処理できた場合はreturn 0;、入力エラーや処理の失敗がある場合はreturn 1;などを返すことで、プログラムの実行結果を外部へ伝えられます。

また、LinuxやmacOSではecho $?、Windowsのコマンドプロンプトではecho %ERRORLEVEL%を使って終了コードを確認できます。これにより、プログラムが成功したか失敗したかを、画面表示とは別に判断できます。

main関数の戻り値を意識できるようになると、Cプログラムを単独で動かすだけでなく、OSやスクリプトと連携するプログラムとして考えられるようになります。