7

重複の可能性:
main()はC / C ++で何を返す必要がありますか?
voidmainとintmainの違いは?

私はいつもCのようにメインメソッドを使用しています

void main(){ // my code }

そしてそれは私にとってかなりうまくいきます。int私は他のリターンタイプについても知ってい ます:

int main(void)
int main()
int main(int argc, char *argv[])

voidしかし、リターンタイプとして使用できると言っているリソースを見つけることができませんでした。intすべての本は、リターンタイプがそうでなければそれが省略されなければならないことを示唆しています。では、なぜ機能void main()するのでしょうか。

これは私が使用しているCのバージョンに依存しますか?それとも、C ++ IDEを使用しているので機能しますか?C++ではなくCに固有の返信をしてください。

4

5 に答える 5

11

voidforの返品タイプmain()が許可されている場所を知っているのは本の著者だけのようです。C++標準はそれを完全に禁止しています。

C標準では、標準形式は次のとおりです。

int main(void) { ... }

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

引数の型に対して代替の同等の形式の宣言を許可します(もちろん、名前は関数のローカル変数であるため、完全に任意です)。

C標準は、「他の実装定義の方法で」小さな規定を設けています。ISO / IEC 9899:2011規格には、次のように記載されています。

5.1.2.2.3プログラムの終了

関数の戻り型がとmain互換性のある型である場合、関数intへの最初の呼び出しからの戻りは、関数によって返された値を引数として関数mainを呼び出すことと同じです。11) main関数を終了するに到達すると、値0が返されます。戻りタイプがと互換性がない場合、ホスト環境に返される終了ステータスは指定されていません。exitmain}int

11) 6.2.4に従い、メインで自動保存期間が宣言されているオブジェクトの存続期間は、後者では終了しない場合でも、前者の場合で終了します。

これにより、int返品不可が明らかになりますが、指定されていないことが明確になります。したがって、一部の実装でvoidはの戻り型として許可されている可能性がありmain()ますが、それはドキュメントからのみ見つけることができます。

(私はC2011標準を引用していますが、基本的に同じ言葉がC99にあり、そのための私のテキストはオフィスにあり、私はそうではありませんが、C89を信じています。)

ちなみに、規格の付録Jには次のように記載されています。

J.5一般的な拡張機能

次の拡張機能は多くのシステムで広く使用されていますが、すべての実装に移植できるわけではありません。厳密に準拠したプログラムが無効になる可能性のある拡張機能を含めると、実装が非準拠になります。このような拡張機能の例としては、新しいキーワード、標準ヘッダーで宣言された追加のライブラリ関数、またはアンダースコアで始まらない名前の事前定義されたマクロがあります。

J.5.1環境引数

ホストされた環境では、main関数は3番目の引数を受け取ります。これは、プログラムのこの実行のための環境に関する情報を提供する文字列を指すchar *envp[]、nullで終了するポインタの配列を指します(5.1.2.2.1 char)。

なぜ機能void main()するのですか?

質問はそれが機能することを観察しvoid main()ます。コンパイラがプログラムのコードを生成するために最善を尽くすため、「機能」します。GCCなどのコンパイラは、の非標準形式について警告しmain()ますが、それらを処理します。リンカはリターンタイプについてあまり心配していません。シンボルが必要なだけでmain_mainシステムによっては、場合によっては)、シンボルが見つかったら、実行可能ファイルにリンクします。起動コードは、mainが標準的な方法で定義されていることを前提としています。スタートアップコードに戻ると、関数がをmain()返したかのように戻り値を収集しますintが、その値はガベージである可能性があります。したがって、プログラムの終了ステータスを検索しない限り、それは一種の機能を果たしているように見えます。

于 2012-06-06T14:01:25.883 に答える
2

馬の口から:

5.1.2.2.1プログラムの起動

1プログラムの起動時に呼び出される関数の名前はmain。実装は、この関数のプロトタイプを宣言していません。intこれは、パラメータなしのリターンタイプで定義する必要があります。

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

    int main(int argc, char *argv[]) { /* ... */ }
または同等のもの; 9) またはその他の実装定義の方法。
9)したがって、intは、intとして定義されたtypedef名に置き換えることができます。または、argvのタイプはchar**argvなどと書くことができます。

抜け穴は「他の実装定義の方法」です。実装(または他のタイプの)main戻りを許可する場合がありますが、そのような署名が許可されていることを明示的に文書化する必要があります。それ以外の場合、動作は未定義です。つまり、コンパイラーは必要なことを何でも実行できます。プログラムは問題なく実行できます。実行される可能性がありますが、環境が悪い状態のままになります。終了時にクラッシュする可能性があります。まったくロードできない場合があります。 void

于 2012-06-06T14:09:38.297 に答える
0

使用しているコンパイラによって異なりますが、voidmainはどこでもコンパイルできるわけではありません。voidmainでプログラムをコンパイルしないコンパイラを見たことがあります。特定のケース(cの場合)を思い出せませんが、これがg ++で発生することは確かです(はい、これはc ++です)。

于 2012-06-06T14:01:02.220 に答える
0

標準ではmain()returnを要求しintますが、多くのCコンパイラでは、のreturnタイプをmain()として指定できますvoid

戻る習慣を身につけることをお勧めしますint。追加する

return 0;

あなたの最後まではmain()あまり努力ではありません。

于 2012-06-06T14:03:14.043 に答える
-1

私はC89で受け入れられましたが、もはや「安全」とは見なされていません。C99では、それはもはや受け入れられません。

http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284376&answer=1044841143

于 2012-06-06T14:03:55.947 に答える