web-dev-qa-db-ja.com

Cのmain()関数

私は数週間独学でCプログラミングを学んでいますが、main()関数に関していくつか質問があります。

  1. すべての関数は、その関数プロトタイプで宣言し、後で定義する必要があります。最初にmain()関数をプロトタイプで宣言する必要がないのはなぜですか?

  2. なぜint main()の代わりにvoid main()を使用する必要があるのですか?

  3. main()関数で正確に0を返すのは何ですか?たとえば、main()関数を_return 1;_で終了するプログラムを書いたらどうなりますか?

24
Heikki
  1. 関数の宣言は、関数が使用される前にのみ必要です。定義自体が宣言なので、事前のプロトタイプは必要ありません。 (一部のコンパイラおよび他のツールは、関数が事前のプロトタイプなしで定義されている場合に警告する場合があります。これは、C言語の規則ではなく、有用なガイドラインとして意図されています。)
  2. C標準がそう言っているからです。オペレーティングシステムは、戻り値を呼び出し元プログラム(通常はシェル)に渡します。一部のコンパイラはvoid mainが、これは非標準の拡張機能です(通常、「常にOSにゼロを返す」という意味です)。
  3. 慣例により、ゼロ以外の戻り値はエラーが発生したことを通知します。シェルスクリプトおよびその他のプログラムは、これを使用して、プログラムが正常に終了したかどうかを確認できます。
19
Fred Foo

1)すべての関数は、関数プロトタイプで宣言し、後で定義で宣言する必要があります。最初にプロトタイプでmain()関数を宣言する必要がないのはなぜですか?

違います。簡単な例:

void foo(){}  //definition

int main()
{
    foo();
    return 0;
}

1つの関数が呼び出されたが、定義がまだ表示されていない場合にのみ、宣言が必要です。 mainはプログラムのスターアップであるため、これは決して起こりません。


2)void main()の代わりにint main()を使用する必要があるのはなぜですか?

規格がそう言っているからです。 (より正確には、ホストされた環境でそれが当てはまります。これは通常そうです)

C99 5.1.2.2.1プログラムの起動

プログラムの起動時に呼び出される関数の名前はmainです。実装は、この関数のプロトタイプを宣言しません。 intの戻り値の型で、パラメータなしで定義されます:

int main(void) { /* ... */ }

または、2つのパラメーター(ここではargcおよびargvと呼びますが、宣言されている関数に対してローカルであるため、任意の名前を使用できます):

int main(int argc, char *argv[]) { /* ... */ }

または同等;または、他の実装定義の方法で。


3)main()関数で正確に0を返すのは何ですか?たとえば、main()関数をreturn 1で終了するプログラムを書いたらどうなりますか?

戻り値は、プログラムの結果を示します。通常、0は成功を示し、他の値はさまざまな種類の失敗を示します。

17
Yu Hao

Mainの戻り値の型を自由に選択することはできませんmainを呼び出すコードを記述しなかったため。 mainを呼び出すコードは、Cの学習について考える前にすでに存在していました。通常、自動的にリンクされるCランタイムスタートアップコードを提供する人々によって書かれました。知らないうちに実行可能ファイルに。多くの場合、このコードはcrt0.o(crt0.cまたはcrt0.sのアセンブラーからも作成されます)というファイルにあります。成功(0)または失敗(非ゼロ)を示す戻り値に加えて、コードがシグナルのために終了したかどうか、そうである場合はどの情報など、その他の情報を使用することを想定しています。これらはUnixの歴史のほんの一部であり、ここでは繰り返しません:-)

2
Jens

1)必ずしもではありません。定義は宣言としても機能します。第二に、mainの有効な署名はとにかく数個しかなく、通常、IOCCCのエントリを作成しているのでなければ、コード内でmainを呼び出すことはありません。

2)簡単な答え:言語定義がそう言っているから。より長い答え:これは、プログラムがホスト環境の成功または失敗を示す方法です。個々の実装はmainの追加の署名を自由にサポートできますが、それらの追加の署名を文書化する必要があります。コンパイラのドキュメントにvoid main()が正当な署名として記載されていない場合は、使用しないでください。

3)慣例により(少なくともCが最初に使用された* nixシステムでは)、ステータス0は成功を示し、ゼロ以外のステータスは...成功以外を示します。正確にどの値がどのステータスが実装次第であるかに対応します。

1
John Bode

すべての質問に最も本質を置くのは、伝統と適合性です。ツールチェーン、オペレーティングシステムなどは、このプロシージャがmain()を呼び出す方法を、ユーザーコードスペース(プログラム)から最初に呼び出す必要があることを知っています...

今具体的には:1)私が言ったように適合のため。ツールチェーンとオペレーティングシステムはすでにmainについて知っているため、宣言する必要はありません。また、exit()などの他の適合関数もあります。

2)メインの時間が戻ると、オペレーティングシステムは結果を返すことができます。通常、ゼロ以外はエラーを意味します。 Uがスクリプトまたは他のプログラムを使用してプログラムを呼び出す場合main()関数、成功したかどうかを確認できます。

3)ゼロ以外の何かを返すことはエラーを意味します。しかし、実際には、その値を希望どおりに解釈できます。しかし、私が言ったように、OSは結果を持つことができます。

追加情報:main()は実際には、プログラムを起動したときに呼び出される最初の関数(記述したもの)ではありません。しかし、実際にはオペレーティングシステムとツールチェーンは、メインの前に他の呼び出しを容易にし、環境をセットアップし、初期化などを行います。しかし、コードを書いているとき、あなたはそれについて直接知りません、そして、あなたはそれを扱って、それについて全く考える必要はありません。組み込みシステムでは、通常、CPUメインクロック、割り込み、スタックなどをセットアップするために呼び出される非常に低レベルの関数がいくつかあります。IARのようなツールチェーンのいくつかは、実際にmainが呼び出される前に独自のコードを実行できるようにします。

これが役に立てば幸いです:)

0
arapEST

関数は必ずしも最初にプロトタイプとして宣言する必要はありません。このような宣言は、定義する前に関数を使用する必要がある場合にのみ必要です。

mainの型はint 定義によるです。

Mainから返される値の意味は従来のものです。一般に受け入れられている慣習では、0は成功と見なされ、0は何らかの失敗ではありません。

0
zentrunix

Cプログラムを実行すると、ComputersコントロールはCプログラムに渡されますmain() function、そこからCプログラムが実行を開始します

0
Chawki

1. main()関数は、組み込みキーワード「main」を認識することにより、Cライブラリによって暗黙的に呼び出されます。したがって、メイン関数のプロトタイプを宣言する必要はありません。

2.これはわかりませんが、使用するエディターのタイプに依存すると思います。 Turbo Cでは、void main()が受け入れられますが、dev-cppではmain()は値を返す必要があります。

3.return 0は単純に終了ステータス0でプログラムを終了します。言い換えると、戻り値はメインスレッドの終了ステータスを決定します。

0
Mahalakshmi

1)falseです。関数の定義のみを作成できます。

2)main()関数が正しく終了したかどうかを知ることができます

3)シェルで0の代わりに1を書き込むことを除いて同じ

0
jambono