• ベストアンサー

forループの中での初期化

http://www.okweb.ne.jp/kotaeru.php3?q=802781 すいません。またわからなくなってしまいました。 class Fooo{   public static void main(String args[]){     int a;     int b=10;     int c;     for(int i=0;i<5;i++){       a=10;       c=b+i;       System.out.print(c);     }     System.out.println(a);   } } 初期化は「確実に」行われていますよね? aが初期化されてない、というコンパイルエラーが出るのです・・・ なぜですか???

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

  • ベストアンサー
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.2

たしかに確実に初期化される《はず》なんですが…… 実はコンパイラには次の(1)と(2)の区別がつきません。 (1) int a; for (int i = 0; i < 5; i++) {   a = 10; } System.out.println(a); (2) int a; for (int i = 0; i < 0; i++) {   a = 10; } System.out.println(a); (1)は問題なさそうですが、(2)は問題ありです。 (2)はループの中身(a = 10;)が1回も実行されません。 さすがにコンパイラはループの中身が1回以上実行されるかどうか判断できないので、(実行時に変わってくる場合もあるし) (1)もエラーにされてしまいます。 でもこういう場合だけは例外的にエラーになりません。 int a; for ( ; ; ) { // ←無限ループになる   a = 10;   break; // ←無限ループから脱出 } System.out.println(a); 同じことですが int a; while (true) { // ←無限ループになる   a = 10;   break; // ←無限ループから脱出 } System.out.println(a); ループの条件に変数の中身がかかわってくるとだめみたいですが、(i < 5 とか i < 0 とか) 条件がコンパイル時定数になる場合はOKみたいです。 # あ~ややこしい。

azicyan
質問者

お礼

いつもお世話になっています。 とてもわかりやすい例でありがとうございます。 確かにforループには0回と言う場合もありえますね・・・。 0回のときのことを考えて、コンパイラははじくのですね。 これで初期化はNOだが、更新はOKというなぞが解けました! 無限ループならOKと言うのは盲点でした。 引っ掛け問題としてでそうですね(笑 大変助かりました

その他の回答 (1)

  • nori_6576
  • ベストアンサー率28% (6/21)
回答No.1

メソッド中に定義した変数(局所変数)は、クラス変数とは異なり、自動的には初期化されません。3行目int a;と5行目int c;は、a=0; c=0;などで、ループの外側で、初期化しておく必要があります。 その変数が、ループ内で単に値を代入されるだけか、それとも、ループしながら加算されていくかは、コンパイラの知るところではないです。 ルールは、局所変数は使用される前に必ず初期化すること、です。 以下、java言語規定から引用します。 --- 局所変数(Local variables) は,局所変数宣言文(14.3)で宣言する。制御の流れがブロック(14.2)又はfor文(14.12)に入ったときにいつでも,そのブロック又はfor文内に直接含まれている局所変数宣言文で宣言した個々の局所変数用に,新しい変数が生成される。局所変数宣言文は,その変数を初期設定する式を含んでもよい。しかしながら,初期化式をもつ局所変数は,それを宣言している局所変数宣言文が実行されるまで,初期化されない。

参考URL:
http://www.y-adagio.com/public/standards/tr_javalang/4.doc.htm#28536
azicyan
質問者

補足

回答ありがとうございます。 初期化はネスとしたところではだめだが、 更新なら良いと言うことでしょうか??

関連するQ&A