Java SE7 Silver の資格を目指し勉強中です。
分からない点は
・ 6,7行目でコンパイルエラーではなく、無限ループになる理由
1 public class Main{
2 public static void main(String[] args){
3 int[] array = {1,2,3};
4 for(int num : array){
5 int i = 1;
6 while(i <= num);
7 System.out.println(i++);
8 }
9 }
10}
答えは「無限ループになり、何も表示されない」です。
これは6行目がwhile(1 <= 1);となるからでしょうか
また、そうした場合、7行目に到達不可能なコードがあるように思い、コンパイルエラーになるのではとも思います。(選択肢には「コンパイルエラーが発生する」というものもあります)
なぜ、コンパイルエラーではなく、無限ループが答えになるのでしょうか
返信は夜になると思いますが、よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
コンパイラの到達不能コード検出は通り一遍のものでして、
条件分岐(ifやwhileのことですね)の条件がどちらに転んだとしてもたどり着けない行があるときだけ検出してくれます。
もしもっと賢く、事実上到達できない行を検出するようにしようとしたらどうなるかというと、実際にコードを実行してみないといけなくなるため、このコードのように無限ループに陥るコードだとコンパイラがフリーズしてしまうことになります。だから、そんな“賢い”到達不能コード検出はされません。
投稿2016/03/23 06:29
総合スコア5568
0
これは引っかけ問題ですね。
ご質問のコードをEclipseなどのIDEに転記し、フォーマットを整形すると以下のようになります。
java
1public class Main { 2 public static void main(String[] args) { 3 int[] array = { 1, 2, 3 }; 4 for (int num : array) { 5 int i = 1; 6 while (i <= num) 7 ; 8 System.out.println(i++); 9 } 10 } 11}
じつは、
java
17 System.out.println(i++);
はwhile
句の外側に位置しており、while
句の中でi++
が実行されないため、正解は
「無限ループになり、何も表示されない」
となります。
---------以下、追記
失礼しました。
これは6行目がwhile(1 <= 1);となるからでしょうか
とおっしゃっているので、無限ループになることは認識されていたのですね。
なぜ、コンパイルエラーではなく、無限ループが答えになるのでしょうか
おそらく、【全ての】到達不可能コードをコンパイラに検出させることが難しいからではないでしょうか?
stackoverflowでも同様の話題があり、多分、そのような回答がなされていますw
ちなみに、以下のようにreturn
句やthrow
句のあとに実行行を書いた場合は、コンパイルエラーとなります。
java
1return; 2System.out.println("hoge");
これは、コンパイラから見ても到達不可能であることが明らかだからだと思われます。
投稿2016/03/23 06:38
編集2016/03/23 06:57総合スコア4791
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
コンパイラの立場になって考えて見れば、
java
1public class Main { 2 public static void main(String[] args) { 3 while(true) ; // 継続条件が確定でtrueで、breakがないから… 4 System.out.println(); // どうやってもここ来れないじゃん -> エラー 5 } 6}
java
1public class Main { 2 public static void main(String[] args) { 3 boolean b = true; 4 while(b) ; //boolean型の変数だけど、変化の余地があるな… 5 System.out.println(); // 変更されたらここに来れるかもしれない 6 } 7} 8
java
1public class Main { 2 public static void main(String[] args) { 3 final boolean b = true; 4 while(b) ; // boolean型の変数だけどfinal?じゃあtrueから動きようないな 5 System.out.println(); // 絶対ここ来れないな -> エラー 6 } 7}
java
1String str = "1"; 2 3if (1 == 2) { // boolean型が返ってくるのはわかるけど、結果は今の時点じゃわからないな 4 str = "2"; // 結果次第ではここ通るかもな 5}
投稿2016/03/23 17:46
総合スコア20651
0
「プログラムが停止するかどうかを判定する」問題は停止問題という名前がつくぐらい由緒正しい問題ですが、「どんなプログラムについても、停止するかしないか正しく判定できる」方法は、存在しないことが示されています。
完璧を実現することは不可能な以上、コンパイラとしても「できる範囲だけすればいい」というわけで、コンパイル時に定数となる条件だけ判定する、というのが通常です。
投稿2016/03/23 07:12
総合スコア145183
0
コンパイラはプログラムを実行しませんので、その時点の変数の値によって無限ループになる構文は、無限かどうか判断できません。
while(true);
と書くと無限ループと判断してコンパイルエラーになります。
投稿2016/03/23 06:39
総合スコア84533
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/03/23 07:20
2016/03/23 11:47
2016/03/23 12:41
2016/03/23 12:57
2016/03/23 19:10
0
Java
1String str = "1"; 2 3if (1 == 2) { 4 str = "2"; //実際は絶対入らないけどコンパイルは通る 5}
みたいなコードでもコンパイルエラーにはなりませんね。
「判定した結果、到達しない」みたいなコードはコンパイルエラーにならない気がします。
判定などの要素が全く無く、かつ絶対にその先には行かない、という場合にエラーになる気がします。
String str = "1"; return; str = "2"; //到達不可能 コンパイルエラー
String str = "1"; if (1 == 1) { return; } str = "2"; //これはエラーにならない
Java
1String str = "1"; 2int num = 0; 3 4if (num == 0) { 5 str = "a"; 6} else if (num != 0) { 7 str = "b"; 8} else { 9 str = "c"; //ここも絶対来ないけどエラーにならない 10}
投稿2016/03/23 07:03
総合スコア1126
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/03/23 19:13