星屑さん>あとWinMainの戻り値って意味があるんですか?
たかぼー>これは知らないです(ぉ
たかぼー>きっと他の人が答えてくれますよ(笑<NUTS氏とか
という会話が、たかぼーのページの掲示板でされてたとかされてなかったとか。
この書き込みを読んでたのか読んでなかったのか、
hiro「main の返値って意味無いじゃん、どこに返るよ?」
とかいうことを授業中に訊かれてみたり。
main の返値が int だって事を知らん奴も居てみたり、stdlib.h に
「#define EXIT_SUCCESS 0
」「#define EXIT_FAILURE 1
」
とか書かれているのを知らん奴も居てみたり、なんなんでしょう、この状況は。
仕方ないから、この状況を少しでも改善しようと思って、こんなものを書くわけです。
まず、結論から言うと、main() の返値や、exit() の引数は「そのプログラムの呼び出し元」に返されます。
で、その「呼び出し元」は大きく 2 つに分けられます。
まず 1 つ目は shell です。(MS-DOS だったら command.com ですね) プログラムの返値は、コマンドインタプリタである command.com に返されて、 バッチファイルでの分岐処理に使われたりします。
例えば、「マシンに故障があったら 1 を、無ければ 0 を返すプログラム check.exe」 というプログラムがあったとしたら、
check.exe
if errorlevel 1 goto NG
if errorlevel 0 goto OK
:NG
echo マシンに異常があります. 点検して下さい.
goto end
:OK
echo マシンに異常は見つかりませんでした.
goto end
:end
というバッチファイルを組むことによって、解りやすく利用することが出来ます。
2 つ目は、他のプログラムが呼び出し元になる場合です。
実際には、C 言語なら spawn() 系の関数で呼ばれる場合ですが、
こうして呼び出されたプログラムの返値は、呼び出した関数の返値になります。
例えば、さっきの check.exe を子プロセスとして呼ぶ場合には、
int rslt;
rslt = spawnl( P_WAIT, "check.exe", "check.exe", NULL );
switch( rslt )
{
case 0:
printf( "マシンに異常は見つかりませんでした." );
break;
case 1:
printf( "マシンに異常があります. 点検して下さい." );
break;
}
といった感じになります。
こうして、他のプログラムとかコマンドを、ちょっとした関数の代わりにして使ったりできるわけですね。
# 実際にコンパイルして走らせてはいないので一寸怪しいのですが……。
# なお、spawn() 系の関数は ANSI 標準の関数セットには含まれていません。
他にも、OS のカーネルから呼ばれる、shell 等のプログラムの返値がカーネルに返る場合が考えられますが、 その辺はよく解らないので省略します。(エー
どの場合でも、main() の返値や exit() の引数は、「そのプログラム自体の返値」になって、 他のプログラムとの連携に役立っているというわけですね。
なお、「プログラムが値を返す」というのは、「main 関数が値を返す」ということと同じですから、
正しい main 関数のプロトタイプは、
int main( int argc, char **argv );
となります。
行儀の良いプログラムは、正常終了時には零を、異常終了時には非零を返します。
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
みたいなマクロが stdlib.h あたりにあるとおもいますが、これがそれです。
FILE *fp;
fp = fopen( "test.txt", "r" );
if( fp == NULL )
exit( EXIT_FAILURE );
みたいな使い方をされることが多いですね。
当然、main関数の末尾は、
return EXIT_SUCCESS;
となるわけです。
% echo $status # csh 系の場合
% echo $? # sh 系の場合
で、直前に実行されたプログラムの返値が表示される。