23

これは、私と私の先生の間の長期にわたる議論です。/ -ループの代わりにforループを絶対に使用できない状況はあり得ますか? つまり、ループの代わりにループが機能しない特定のケースがあります。/ -は?と何らかの形で「異なる」whiledowhileforwhilewhiledowhilefor

4

4 に答える 4

37

いいえ、そのような状況はありません。すべてのdo-whileループは、(ループの前に本体を 1 回実行することにより) - ループで記述できwhile、その逆も可能です。次に、すべてのwhileループ

while (X) {
    ...
}

次のように書くことができます

for (; X;) {
    ...
}

つまり、初期化ステートメントとインクリメント ステートメントを省略します。初期化とインクリメントを正しく配置することで、foraから a に変換することもできます。while

要するに、1 つのループ バリアントから他の 2 つのいずれかに変換することは常に可能です。for-loops は、ループ制御変数のスコープを制限し、上部でインクリメントを実行できるという利点を提供します。言うまでもなく、多くの場合、特定のループ バリアントを使用すると、他のバリアントよりもはるかに意味があります。それぞれに特定のユースケースがあります。

また、楽しみはループで終わるだけではないことに注意してください: すべてのループを再帰関数に変換することも、その逆も可能です (ただし、実際にはこれには制限がある可能性があります。たとえば、うまく機能したループは、再帰関数を使用すると、スタック オーバーフロー エラーが発生します)。


[I]s while/ do-いずれにしても?whileとは「異なる」for

そうではない。たとえば、次の 2 つのスニペットのバイトコードは同一です。

int x = 0;
while (x < 10) {
    x++;
}

int x = 0;
for (; x < 10;) {  // or: for (; x < 10; x++) {}
    x++;
}

どちらも次のようになります。

   0: iconst_0      
   1: istore_1      
   2: goto          8
   5: iinc          1, 1
   8: iload_1       
   9: bipush        10
  11: if_icmplt     5
  14: return 

for-eachループに関するコメントで、他のループ タイプとは本質的に異なる可能性があるという話がありました。これは絶対に真実ではありません。for-each ループは、反復子 (または配列のループ) を囲む純粋な構文糖衣です。every for-each ループは、他の各ループ タイプに変換することもできます。次に例を示します。

for (String s : l) {  // l is a list of strings
    System.out.println(s);
}

String s;
Iterator<String> iter = l.iterator();  // l is a list of strings
while (iter.hasNext()) {
    s = iter.next();
    System.out.println(s);
}

どちらも次のようになります。

  24: invokeinterface #33,  1           // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
  29: astore_3      
  30: goto          50
  33: aload_3       
  34: invokeinterface #39,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
  39: checkcast     #19                 // class java/lang/String
  42: astore_2      
  43: getstatic     #45                 // Field java/lang/System.out:Ljava/io/PrintStream;
  46: aload_2       
  47: invokevirtual #51                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
  50: aload_3       
  51: invokeinterface #57,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z
  56: ifne          33
于 2013-10-09T17:24:16.247 に答える
6

いいえ、いつでも for ループを while ループとして書き直すことができます。

<init>
while (condition) {
...
<increment>
}

次と同等です。

for (<init>; <condition>; <increment>) {
...
}
于 2013-10-09T17:24:45.397 に答える
0

"絶対"?いいえと思います。 ただし、Java の do-while とも呼ばれるループ後のテストでは、かなり複雑な "for" 条件が必要になります。これにより、ブール値の絶対値に戻ります。条件は、true または false を評価する必要があります。

そのため、コンパイラが正しいロジックを実行するように操作できないケースを想像することはできませんが、プログラムを保守している誰かがあなたを石打ちにしたい (またはおそらくあなたがすでにそうだったと思う) 可能性があることは非常に短い順序でわかります。

関連する注意事項として、機械語で実行できないことで Java で実行できることはありません。しかし、機械語を使用しないことには、実に多くの正当な理由があります。それらのほとんどは、コードを「かわいく」書こうとするときにも同様に適用されます。0300 で怒っている顧客、上司、またはその両方と電話をするまでは、すべてが楽しくゲームです。

于 2013-10-09T17:36:16.467 に答える