□ main の戻り値の型は void でなく int

 OS環境下のCプログラムでは 基本的に
  int main(void)
  {
    printf("hello,world\n");
    return 0;
  }
のように必ず関数の戻り値の型を int にして、return で値を返すように書きます。

return 値は OS に返すエラーコードで
  0ならば正常終了
  0以外ならば異常終了
となっており、C標準関数のexit関数の引数の値と同じものが指定できます(exit関数は、プログラムを終了させる関数で、その引数はOSに返す値になります)。

もっとも main の return 値がこのように決まったのは ANSI-C89/ISO-C90 からで、それ以前(K&R)では return 値 の扱いが不定なことから
  void main()
  {
    printf("hello,world\n");
    exit(0);
  }
ようにexitを用いて終了していました。

ANSI-C89/ISO-C90 において main()関数は、最初に呼ばれるという以外は、他の関数と同様の存在なため、
  void main()
  {
    printf("hello,world\n");
  }
のように exit(0) や return 0; をつけなかった場合、 OSに返すエラー値として、適当なゴミの値が返されてしまいます。

(※ もっともOSにエラーコードを返しても (特に)Dos/Windows環境だと無視されることが多いので、不具合だと思っていない人も多いかもしれません。 が make(makefile) で使ったり バッチで errorlevel 見たりする機会があったりすると無作法に適当なエラーコードを返すプログラムはバグってる状態で鬱陶しいものなので、 return 1行書く手間を惜しまないほうがよいと思います)


と、ANSI-C89/ISO-C90 ではこれだけだったのですが、 C++ および C99 以降においては main関数は特別な扱いをすることになっていて 関数の最後に return 値; がない場合は return 0; がされているのと同じ動作になるコードが暗黙に生成されることになっています。 void main(引数) で定義してもマシン語レベルでは return 0 したのと同じコードが付加されてOSに返す値が0(エラー無)になります。 ただ、C++98対応でも古いコンパイラには暗黙のreturn 0がつかないものもありますし、暗黙のreturn 0はつくけど、void main だとエラーになる(多分int mainでプロトタイプ宣言済)コンパイラ環境もあるので、 int main(引数) で return 0; しておくのが無難でしょう。