アプリ版:「スタンプのみでお礼する」機能のリリースについて

僕が今習っている学校では、『#include <stcio.h>』のあとに『void main()』と書きます。※『;』はつけません。

しかし、参考書などを見ると、『int main(void);』と書いてあります。これ(int main(void))はどういう意味なのかが知りたいのですが・・・。

あとできれば、『void main()』との違いも書いてくれれば幸いなのですが・・・。

回答お願いします。

A 回答 (10件)

★main() 関数の定義例


・(1)void main( void )
 (2)void main( int argc, char *argv[] )
 (3)void main( int argc, char *argv[], char *env[] )
 (4)int main( void )
 (5)int main( int argc, char *argv[] )
 (6)int main( int argc, char *argv[], char *env[] )
 上のように main() 関数の定義にはバリエーションがあります。
・学校で習っているものは(1)ですね。私は普段(4)か(5)を使います。
 基本的に戻り値には void にしない方針です。
・それで(1)と(4)の違いは戻り値を戻せるかどうかの違いです。
 普通コマンドラインから実行したプログラムが int main() 関数を抜けると
 呼び出しもとのOS(Windowsなど)に終了コードが返されます。この終了コードは
 バッチファイルなどで利用したり出来るため int main() 関数でリターン値に
 意味が出てきます。でも終了コードを特に必要としない(意識しない)場合は
 強制的に『0』を戻したり、あるいは最初から void main() として定義します。
 『void』とすると main() 内では戻り値を返せなくなりますが、返す必要が
 無いために void にしているので構いません。なお、OS とかには終了コードは
 未定義のデタラメの値が返されることになります。終了コードを利用しないので
 やはり問題ありませんね。
・よって void main() と int main() の違いは main() 関数がリターン値として
 値を戻すと呼び出し元(OS や他の親プロセス)に終了コードを渡せるかどうかの
 違いです。バッチファイルなどで『IF ERRORLEVEL 数値 命令』という感じで
 使わせるプログラムの場合は int main() と戻り値を返せる状態で定義します。
 そして return 数値; とすることでプログラムが終了したときに終了コードを
 バッチファイルで受け取れるようになるのです。
・学校で習っているサンプル・プログラムではそこまで考えて作ることは無いためか
 void main() としているのでしょう。参考書の方は int main() となっていますが
 多分すべて return 0; を返していませんか?私も終了コードを必要としない場合でも
 void main() ではなく int main() と定義して使います。使う理由は『0』を正常に
 終了したという意味ではっきりと呼び出し元に返すためです。例え『0』しか返さなくても
 そうしてしまいます。癖かな。

その他:
・上記の(2)、(5)はコマンドラインから引数文字列を受け取るときの指定です。
 上記の(3)、(6)はコマンドラインの引数以外に環境変数の文字列テーブルを受け取れる指定です。
 ただし、(3)、(6)は処理系によってサポートされていないこともあります。
・どの処理系でもきちんと利用できるのは(1)、(2)、(4)、(5)の4つだけです。
 それ以外は処理系で自由に決められた文字列を受け取れたりします。なので上記の(3)、(6)は
 とある処理系の場合のことを書いたのです。よって移植性も考えると(3)、(6)以外にします。
・以上。
    • good
    • 1
この回答へのお礼

びっしり書いてくださってありがとうございます。

他のmain()のパターン書いてくれたので、「こういうのがあるんだとなぁ」と勉強になりました。

回答ありがとうございました。

お礼日時:2007/07/28 22:56

>- 上3つの方法のいずれでもない処理系定義の方法



つまり関数名がmainでなくても良い。

ウィンドウズアプリはWinMainで書き始めたりするけど、普遍ではない。

初心者には未規定やら処理系定義をそれとなしに避けて教えるのが上手いやり方だと思うのだけど、
あえて向かっていく意義は?

#家では上手く行きませんという質問が溢れる現状
    • good
    • 0

> 古い規格を元に今でもvoid main()を使えないと思っていませんか?



議論する気はありませんが、ISO/IEC9899:1999での現状追認は知ってますし、
C99準拠になっていて処理系定義なら合仕様なことは理解してます。

但し、現実的には、例えばC99指定したGCCなどを除くと、
現行VCやBCC等はC99準拠でもJISX3010準拠でもないコンパイラですので、
もしもこれらでvoidを使って教えてるならやはり不適切といっていいと思ってますし、
言語仕様の変遷や経緯とか普通いきなり説明しないでしょうから、
どうせ呪文のように教えるなら、なぜ明示規定のintにしないのか。
初心者にいきなり明示規定でない処理系定義なものを教えてるなら、
その姿勢も不適切といって過言ではないとは思ってます。
    • good
    • 0

規格上使える使えないと、一番最初に教えてよい悪いは別でしょう。



Windows/MAC/UNIXでのセルフ開発形態でのC言語教育(あるいはC言語を用いてプログラミング教育)なら、int mainが基本。void mainは応用技。
それとも、void mainと一緒にvolatileやinlineも最初から教えますか?

小学生に野球をやらせるときにいきなり変化球をやらせる指導者は「不勉強すぎ」と言って良いと思いませんか?それと同じ。

これが、組み込みシステムを扱う会社での新入社員へのOJTならまた話は別ですけどね。
    • good
    • 0

>そういう意味で、初心者にvoid main()を教える学校や、void mainと書いてあるC言語入門書は不勉強すぎ。



古い規格を元に今でもvoid main()を使えないと思っていませんか?
C89からC99の直前まで禁止されていたことを、いまだに引っ張らないでください。

C99及びJIS-Cでは使用できます。

JIS-Cから引用ここから
Page 8(途中省略してあります)
5.1.2.2.1 プログラムの...次の4種類の方法のいずれかで定義しなければならない。

- int main ( void ) { }
- int main ( int, char *[] ) { }
- 上2つと等価な方法
- 上3つの方法のいずれでもない処理系定義の方法

Page 9(途中省略してあります)
5.1.2.2.3
main関数の返却値の型がintと適合しない場合、ホスト環境に戻される終了状態は、未規定とする。

Page 3
3.4.4 未規定の動作 この規格が、二つ以上の可能性を提供し、個々の場合にどの可能性を選択するかに関して何ら要求を課さない動作。
    例 未規定の動作の例としては、関数の実引数の評価順序がある。

ここまで

これを読むとvoid main()と書くのは、規格内です。
    • good
    • 0

さらに蛇足を。



C言語に限らず、関数(手続き)を呼び出す側と呼ばれる側では戻り値の型が合致していなければなりません。(呼ぶ側が期待する戻り値の型と、呼ばれる側が実際に返す戻り値の型)
そしてmainを呼び出す「スタートアップルーチン」は、Cコンパイラが用意するものだと思ってください。

int main(・・・)と適合するようなスタートアップルーチンを持つCコンパイラは、「規格の規定どおりCコンパイラ」です。

void main(・・・)と適合するようなスタートアップルーチンを持つCコンパイラは、「規格の規定から外れた独自拡張をしたCコンパイラ」です。

以上の議論は、Cコンパイラが規格準拠かどうかの議論だということに注意してください。

一方、コンパイラの利用者(一般プログラマ)がmain()まわりをどう書くのが正しいか、ですが、
学校でC言語を習うときにはたいていWindowsやUNIXのCコンパイラを使います。これらは、int main(int argc, char *argv[])と適合するようなスタートアップルーチンを持つわけです。なのでmainのほうも
int main(int argc, char *argv[])
と書かなければなりません。ただ、渡された引数をmain側で無視しても特に問題ないので、
int main(void)
もアリです。
ただ「私がこれから書くプログラムは値を返さないから・・」といってみても、スタートアップルーチンの側の記述は固定的なので、main側で勝手に void main(・・・・としてはいけません。

現状の多くのWindows用コンパイラは、void main(と書いてもエラーとはしないですし、それをコンパイルして出来たプログラムも特に問題なく動きます(戻り値としてゴミ値を返してしまっているのですが)。

特定のコンパイラ、特定の対象環境で動く特定のソフトウェア製品を作ろうとするプログラマは、int mainだろうが void mainだろうが、目的に合致したものを選択すればよろしい。それが適切に選択できるのがプログラマの技量のうちです。

しかし、C言語を教育する場合は、「C言語の規格に合致するCコンパイラならどんなOSのどんなコンパイラでもうまくいく筈の、一般的な/コンサバティブな書き方」を教えるべきです。
「とりあえず演習に使う環境で問題なさげに動けばそれでいいい」というのは教育者の態度としてはいかがなものかと。
そういう意味で、初心者にvoid main()を教える学校や、void mainと書いてあるC言語入門書は不勉強すぎ。私に言わせれば失格です。
    • good
    • 0

# 他の回答もろもろの補足を。



言語仕様書で保証するmainの定義は以下の二種類だけです。
int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }
但し、仕様ではその他の処理系定義も許されるので、
他はのきなみ各コンパイラ/OSの慣習/独自定義です。
既にあるように、組み込みなどではvoidにする環境もあります。

また、第三引数envpについては言語仕様の
「Annex J.5.1 Environment arguments」で、
「以下の拡張は多くのシステムで広く使われているが、
 しかし全ての実装に対する移植性はない」と書かれています。
基本的にOS都合であって言語の標準仕様ではありません。

また、0が正常終了を示す標準マクロEXIT_SUCCESSとして定義されているのは確かですが、
異常終了を示す方は1とは限りません。(現実には1が多いですが>UNIX界隈)
<stdlib.h>にEXIT_FAILUREマクロが規定されているだけです。
    • good
    • 0

C/C++言語ではプログラム開始関数であるmainはintを戻り値とするのが基本です。


戻り値は0が正常終了で1が異常終了というのが規格で定義されています。
現在の規格では値を返すreturnが無いまま関数ブロックが終了しても良く、関数ブロックの最後まで実行されたときは0が返されることになります。

戻り値をvoid型にしたり、0、1以外の値を返したり、-1を返したつもりが255になってて悩んだり(これは余談)するのは、上記を踏まえた上でやるべことかと思います。

int main()とint main(void)の違いですが、
前者はC言語では関数呼び出しで引数のチェックをしない、
C++言語では引数が無いことを示します。
後者はC/C++言語ともに引数が無いことを示します。
    • good
    • 0

高校一年生の授業ですか?だったら、まだ理解する必要はないと思うのでが、一応簡単に書いておきます。


int main(void)を例にすると
intで、プログラムを動かすためのメモリを確保します。変数の宣言で使うときのものとは、別です。それは、変数の保存用、これは、プログラム本体の保存用です。
で、mainでプログラムの名前をつけています。長いプログラムになると
int main(void)
{
printf("何か\n");
}
int sub(void)
{
printf("何か\n");
}
のように、複数のプログラムを一気に、一つのソースに書くことがあります。そのときに、区別をつけるために名前をつけているだけです。
voidはプログラムの形をしめしています。これは、こう打つのだと暗記してください。

これは、いろいろと融通が利くので、いろいろなパターンで打つことができます。また、intとvoidは省略が可能なので、
main ()
と略すこともできます。
詳しくは、学校の先生に聞いてみてください。ただ、完全に理解するのには、高等数学の力を借りる必要があります。
    • good
    • 0
この回答へのお礼

だいたい理解できたかなぁ・・・。

高等数学の力を利用するって、どんだけぇ~(意味不明)

学校先生にも詳しく聞いてみます。

回答ありがとうございました。

お礼日時:2007/07/28 22:45

C言語を習っているのならCの教科書も持っているでしょう。

それを読めば書いてあります。

普通のパソコンなど、OS(たとえばWindows)ができあがったプログラムを起動するような環境では、mainはint型と決まっています。

それをvoidとして教えるような学校は
・ダメな学校
・組み込み用C言語を教えている
のどちらかです。

main(void)の括弧の中のvoidは、「引数は無い」という意味です。引数がないことはmain()で表せばいいようなものですが、歴史的経緯で明示的に引数0個を示す場合は voidと書きます。

int main(void) あとに;が有るのと無いのとは、mainの定義をしているか宣言をしているかの違いです。

この回答への補足

組み込み用C言語って何ですか?

補足日時:2007/07/28 22:36
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!