• ベストアンサー

main関数終了時のreturnの意味は?

質問の題名通り、main関数終了時のreturnの意味が知りたいです。いつもは参考書に書いてある通り、return 0とやっていたのですが、参考書のサンプルプログラムでreturn 1というのがでてきた為、少し混乱しました。 参考書に説明が載っていないのでmain関数内でのreturnの意味をご教授願いたいです。よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.6

# 4です。 まず、0を返そうが、1を返そうが、そのプログラム自体の内部的な動作は通常変わりません。 戻り値で動作が変わる可能性があるのは「そのプログラムを呼び出したプログラム側」です。 例えば、make から呼び出された場合にそのプログラムが0以外が返したら、makeは「そのプログラムは失敗した」と考えて、処理を中断したりします。(続けて欲しいなら「成功」を返す、こういうために使います) コマンドラインからあなたが手で入力したのなら、何も起きないかもしれません。 1を伝えられたOSが何をするかは環境(OS)によります。 gccは、Windows版もLinux版も各UNIX版もあるようなコンパイラですから、その版によって違う可能性があります。 ちなみに、手元の Minimalist GNU for Windows では 1 は EXIT_FAILURE でした=つまり前述のような失敗。 別のOS上のgccでは別の値にポートされている可能性も否定はできません。 C言語が保証しているのは、EXIT_SUCCESSを返したとき、その環境では成功と判断してくれるだろう値を返すことと、EXIT_FAILUREのときは失敗と判断してくれるだろう値を返すことだけです。 0は通常EXIT_SUCCESSですが、1はEXIT_FAILURE とは限りません(現実的には 0 と 1 が大半だと思いますが、EXIT_FAILUREが-1とかでも違反ではないです)。 但し、実際に判断できるかはOSにもよりますし、呼び出したプロセスがどう判断するかにもよります。 なお、Windows や Linux, その他私の知っている UNIX では、1を返されたからといって必ず何かが行われるということはありません。 前述のように、別のプログラム等から呼び出された場合に、そのプログラムが失敗と判断して何か処理を行う可能性はありますが、これらはあくまで呼び出し元のプログラムによります。 ITRON等の組込みOSでは、main が値を返す事は通常ありません。 憶測ですが、参考書のサンプルで return 1;となっているのは、例えば argv が求めているものと違うとか、fopen に失敗したとか、そういうケースではありませんか。 そういう異常処理が発生した場合に、もしも呼び出したプログラムがいたらそれを伝えられるように、EXIT_SUCCESS (0)以外の値を返すのは慣習です。 具体的にどんな値を返すかは、プログラムの設計次第になってしまいますが、1や-1を返したり、失敗原因ごとに決めた値を返したりします。 汎用性を重視するならEXIT_FAILURE等もありますが、知名度もやや低いですし、0以外なら何でもいいという認識の人も多いように思いますので、サンプルは単に1を返しているのではないかと。

その他の回答 (7)

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.8

returnで何を返そうが内部の動きは変りません. 影響があるのは外部です. で,外部(OSなど)が返された値をどうするかといえば,OSによって違います. たいていは,起動したプログラムに伝えます.そのプログラムが伝わった値をどうするかは,プログラマが決めることです. 無視することもあります.あるいは,そもそもプログラムを起動しておいて終了ステータスをOSから受け取らないプログラムもあります.

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.7

#5です。 > 使用しているコンパイラはgccです、EXIT_FAILUREの時はこんな風に内部的な動きとかは無いのでしょうか? gccはコンパイラだけですので、標準ライブラリないしはスタートアップがどうなっているかが重要です。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

main関数内のreturnで返す値は、exitに引数として渡す値と同じ意味です。すなわち、EXIT_SUCCESS(=0)であればプログラムが成功したことを、EXIT_FAILUREであれば失敗したことを意味し、それ以外の値は処理系によって意味が異なります。 return 1;と書いた場合、EXIT_FAILUREがたまたま1に定義されていれば失敗を意味しますし、それ以外なら処理系定義ですので、全く移植性のないコードということになります。 また、mainの返却値型はint型が基本ですが、特定の状況では他の型、例えばvoid型の場合もあり得ます。その状況というのは、 1. 組み込み用の処理系など、フリースタンディング環境である場合、処理系定義の型となり得る。 2. C99(C言語の第2版)であれば処理系定義の型となり得る。 3. 処理系が標準規格に合致していない場合、あらゆる可能性が考えられる。 さらに、main関数にreturn文がない場合でも、何らかの値が返されるわけですが、その値は不定(未規定)になります。ただし、C99やC++であれば0が返されます。 使用されている処理系を補足していただければ、それに特化した説明ができるかもしれません。 参考書は、特定の処理系を使うことを前提としたものではありませんか?もしそうでなければ、その参考書を参考にするのは、今すぐやめましょう。

C_32767
質問者

補足

使用しているコンパイラはgccです、EXIT_FAILUREの時はこんな風に内部的な動きとかは無いのでしょうか? 1を返しても0を返しても同じということなのでしょうか?

  • MrBan
  • ベストアンサー率53% (331/615)
回答No.4

一応、C言語仕様上で、<stdlib.h>に EXIT_SUCCESS / EXIT_FAILURE というマクロの定義があります。 (ISO/IEC9899:1999 7.20 General utilities <stdlib.h>) 実際の値は、環境に依存しますが、 VC.NET2003では以下の値で定義されています。 #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 ※成功時にゼロを返すのは、C言語の「お約束」です。 また、main 関数は、return を省略すると 0 を返す仕様です。 戻り値が int 互換でない場合の動作は未規定です。 <5.1.2.2.3 Program termination> 通常は、シェルスクリプトやバッチファイルなどから、 結果を受け取る場合などにこの値を利用するのは、 既に説明のあるとおりです。

C_32767
質問者

補足

1を返した時の内部的な動きが知りたいのですが1を返したときはどのようなことになるのでしょうか?

  • suseimei
  • ベストアンサー率35% (17/48)
回答No.3

> 参考書に説明が載っていないのでmain関数内でのreturnの意味をご教授願いたいです。 面白いとことに注目されましたね。詳細は、次のURL情報を参考にされるとよいと思いますが、 http://ttoyota.com/freetutorial/cppnovice02.htm Microsoftなどの最新環境では、標準言語仕様に準拠するため、このあたりのコンパイラ実装部が多少変更されているようです。 ちなみに、returnを記述しない場合、次のようなアセンブラーコードが追加されることがあるようです。 xor eax, eax これはeaxレジスタを0クリアーするコードです。

C_32767
質問者

お礼

ご回答ありがとうございました。 アセンブラーコードも勉強したほうが理解が深まるようですね。参考URL、とても勉強になりました。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.2

Cのプログラムは,何か別のものに呼び出されて起動します.終了時には,呼び出し側に情報を伝えるためreturn文を使用します. 通常はOS(を経由して,そのプログラムを起動した親プロセス)に正常終了/エラー終了の別を伝えます. 本当は,Cの規格書ではこのあたりには厳密な専門用語を使った規定が書いてあります. mainのリターン値の使い分けについては明確な規定がありません. 正常終了は0,というくらいです.0以外の値のエラーコードはC言語的には決まってないので,OSごとのアプリケーション作成慣習に従うと言うことになります.正常/エラーの二つしか終了状態を区別しないようなプログラムでは0と1を使うのが普通ですね. sysexits.hというのがあって終了コードを定義していますが,これを使うことがC言語的に義務ずけられているわけではありません. OSが存在しない組み込みなどでは誰から呼び出されたわけでもなくCプログラムが動き出すという世界もありますが,そのような場合はreturnしませんね.returnするしないにもかかわらず,mainはint型というお約束です.mainがvoidになっているというのは駄目な参考書/教科書を見分ける参考指標でもあります. ただし,void main(・・・)として書いても,コンパイルはできるし作られたプログラムは動作はしますが.

C_32767
質問者

補足

もしも1を返し、OSにそれを伝えた場合はどのような動きがあるのでしょうか?

  • techa
  • ベストアンサー率60% (41/68)
回答No.1

C言語でのmain()も関数であり、戻り値を要しない場合にはvoid型での利用が可能です。 ただ、コマンドラインで利用する場合などでは int型で定義して return 0; return 1; などのようにすれば、標準出力としてその値が返されるので、結果に応じた処理が可能となるのです。 ここで0を返すか1を返すかは、ソフト作成者の思想に任されているので、あまり深く考える必要はないようにおもいます。 ちなみに私は、エラー終了したのでない限り1を返すように記述しています。 利用は真=1、偽=0というのが思想的にわかりやすいからです。(偽=0というのは一般的ですが、真≠0ともいえますから、必ずしも1とは限りませんが)

C_32767
質問者

お礼

ご回答ありがとうございました。 returnでどちらを返してもよいということですか。 なんだか難しいですね。

関連するQ&A

  • main関数の戻り値

    C言語のmain関数の戻り値はint型ですよね。 私もそういう決まりだと思って守ってきました。 しかし、「mainが戻り値を返すって、どこに返すの?」ということが、私は理解できていません。 私が調べたところでは、「ホスト実行環境」という言葉がこの問題に関係あるようですが、この言葉の意味はよくわからないですし、似た言葉で「ホスト環境」ということばがあるのですが意味も関係もわかりません。 これらは、OSとは違うと思うんですが、自信はありません。 それでも、ない知識を振り絞っていろいろ考えてみると、次のようなことらしいのですが、正しいでしょうか。 ・OSはプログラムの実行に先立ちホスト実行環境を作る。 ・静的記憶域のオブジェクトを初期化するのはホスト実行環境である。 ・関数が、main関数を呼ぶことは可能である。(以下では、main関数が関数から呼ばれる場合は除く。) ・main関数を呼ぶのは、ホスト実行環境が行なう。 ・main関数の中のreturnによってプログラムが終了するのと、exit関数でプログラムが終了することに違いはない。 ・main関数の戻り値は、ホスト実行環境に返される。 ・returnによってホスト実行環境に返される値は、int型である限りなんでもよい。 ・exitによってホスト実行環境に返される値は、int型である限りなんでもよい。 ・必ずexitで値が返されるならば、main関数の中にreturnはなくてもよい。 main関数からの戻り値をどうしようと構わないんだと思うんですが、皆さんの経験の中で、実例としてこういうふうに使われる、というのは何かないのでしょうか。 (ホスト実行環境に値が返される、といっても無視するのでは意味はないと思うのです。 その値の使用例としては、 0が返ってくると「プログラムは正常終了しました。」と表示するとか、0以外の値が返されると別のプログラムが走るとか、 そういうことだと思うんですが。)

  • C言語でmain関数でのreturnとexit

    C言語でmain関数でのreturnとexitは同等とされてますが、 それは『プログラムを呼び出した元の動作』も同じですか? 例えばshellやOSから見て、割り当てメモリ開放などの点で returnで終了したプログラムの後処理と exitで終了したプログラムの後処理は 全く同じになりますか?

  • main関数の戻り値について

    c言語において、main関数の戻り値は何を意味しているのですか。 また、void型にすれば、main関数の戻り値を書かなくても問題無いでしょうか。 また、関数はreturn文を書かなくても、最後まで処理を実行すると終了するらしいですが、void型にすれば、main関数でreturn文を書かなくても問題無いでしょうか。

  • main文のreturnは0以外は何ができるの?

    はじめまして。c初心者です。 main文の最後に書くreturnはreturn 0 の0を変えると、プログラムが終了した後、もう一度起動するみたいな話を聞いたことがあります。returnについて教えていただけませんか?よろしくお願いします。

  • プログラムがmain関数から始まらない??

    C言語初心者です。よろしくお願いします。 return文について勉強している途中だったのですが、次のプログラムを実行してみたところ、わからないことが出てきたので質問させていただきました。(ほとんど自分で作ったプログラムではないです) #include <stdio.h> /* 関数a()はintを返すと指定 */ int a() {     if (1) {          /* ここで関数a()は終わります */          printf("yes1\n");          return 300;     }     pritnf("yes2\n");     /* ここは通りません */     printf("this is a()\n");     return 10; } int main() {     int i;     /* 関数a()の返り値を変数iに代入します */     i = a();     printf("i = %d\n", i);     return 0; } このプログラムの出力結果は yes1 i = 300 となるのですが、 1.以前「main関数からプログラムは開始する」というようなことを学習したのですが、このプログラムではyes1が出力されていることからa関数からプログラムが始まっていませんか? 2.a関数のif文の中のreturn 300;でプログラムが終了しないのはなぜですか? 知識のある方、どうか教えてください。 よろしくお願いします。 ※ このプログラムを表示させる際、Tabキー及び半角では適度な空白スペースを作ることができなかったので、プログラムを見やすくするための空白スペースは全て全角スペースで作ってあります。(もしかしたら普通に表示させる方法があるのかもしれませんが、わかりませんでした。)

  • main()とint main(void)の違い

    最初main()と習ったのですが、最近学校でmain()ではなくint main(void)を使うように なりました。 どのように違うのでしょうか? main関数のところに引数が入っている意味がわかりません。 (void)ってなんですか? そもそも引数って何ですか? あと、プログラムの最後にreturn(0)って書いてあるんですが、これはどういう意味ですか? 回答よろしくお願いします。

  • C言語で、自分で作った関数内で終了させるには

    C言語なのですが、自分でエラーチェックをする関数を作りました。 エラーを検出した時点でプログラムを終了させたいのですが、 どのようにすればいいのでしょうか? return 0; はmain関数を終了させるときに使うのはわかるのですが… 初歩的な質問かもしれませんが、よろしくお願いします。

  • C言語 main関数とsum関数の記述順について

    はじめまして。 【苦しんで覚えるC言語】(Web版)でC言語を学んでいる初学者です。 【第1部:C言語基礎編】>【関数の作り方】>【自作関数を作る】の部分(http://9cguide.appspot.com/11-01.html#S2)でつまづいています。 下記のような、1から100までの数字の合計を表示するプログラムが例題として取り上げられています。 しかし、ここが理解できないので、次の【プロトタイプ宣言】に進めずにいます。 例題1  sum関数をmain関数の後に記述した場合(プログラムが実行されない)。 #include <stdio.h> int main(void) { return 0; } int sum(void) { printf("%d\n",(1 + 100) * 100 / 2); return 0; } 例題2  sum関数をmain関数の先に記述した場合(プログラムが実行される)。 #include <stdio.h> int sum(void) { printf("%d\n",(1 + 100) * 100 / 2); return 0; } int main(void) { return 0; } 例題1の場合、【まずmain関数を作り、次にsum関数を作りました。この場合、main関数を解析している段階では、sum関数は発見されておらず、従って、main関数の中では、sum関数を使うことは出来なくなってしまいます。】との説明がありますが理解できません。 コンパイラがどのような順番でプログラムを処理しているか理解できていないので分からないのだと思います。 例題1の場合と例題2の場合の両方について、コンパイラがどのような順番でプログラムを処理しているのかを具体的に教えてください。 どうかよろしくお願い致します。

  • 関数をこえてプログラムを強制終了させる方法

    main関数以外の関数からmainのreturnに移動して終了するにはどうすればよろしいのでしょうか?。main関数以外の関数からgotoでreturnの前まで移動しようとしたら関数を飛び越えて移動できませんとエラーが起こりました。関数をこえて強制終了させる方法を知っている方お願いします。教えてください。

  • 初期化は、main関数の外で行うものなのか

     ルネサスHEWのサンプル・プログラムを見ると、I/Oの初期化、Bセクションのクリア、DセクションからRセクションへのコピーなどを行ってから、main関数に飛んでいます。  これらの初期化はメイン関数の中で行うべきだと思っているのですが、どうなんでしょう。  パソコンでexeファイルを実行した場合、mainに飛ぶと思っているのですが、初期化プログラムに飛んでからmainに飛ぶのでしょうか。  宜しくお願いします。

専門家に質問してみよう