23

这是我和老师之间长期存在的争论。是否存在绝对不能for使用循环来代替/ -循环的情况?换句话说,是否存在特定情况下-loop 不能代替循环工作?是/ -以任何方式“不同” ?whiledowhileforwhilewhiledowhilefor

4

4 回答 4

37

不,没有这种情况。每个do-while循环都可以写成- 循环while(通过在循环之前执行一次主体),反之亦然。反过来,每个while-loop

while (X) {
    ...
}

可以写成

for (; X;) {
    ...
}

即我们省略了初始化和增量语句。我们还可以通过正确放置初始化和增量for来将 a 转换为 a。while

简而言之,总是可以从一个循环变体转换为其他两个循环变体中的任何一个。for-loops 只是为您提供了能够限制循环控制变量的范围并在顶部进行任何增量的好处。不用说,在许多情况下,一个特定的循环变体比其他循环变体更有意义。每个都有其特定的用例。

另请注意,乐趣不仅仅以循环结束:还可以将每个循环转换为递归函数,反之亦然(尽管在实践中可能对此有限制;例如,一个运行良好的循环可以,当转换为递归函数,产生堆栈溢出错误)。


[I]s while/ do-while以任何方式“不同” for

它不是。例如,以下两个片段的字节码是相同的:

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 循环是迭代器周围的纯语法糖(或遍历数组)。每个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 循环,而任何 while 看起来都为 for 循环。

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

相当于:

for (<init>; <condition>; <increment>) {
...
}
于 2013-10-09T17:24:45.397 回答
2

其他答案已经涵盖了while循环和for循环之间的等价性。那是,

while(<expr>) {
  <body>
}

相当于

for(;<expr>;) {
}

请注意,可以使用do-while循环进行类似的缩减。任意循环do_while

do {
  <body>
} while(<expr>);

在功能上等同于

for (boolean firstIter = true; firstIter || <expr>; firstIter = false) {
  <body>
}
于 2013-10-09T18:46:00.580 回答
0

“绝对地”?我会说不。 然而,Java 中的循环后测试(又名 do-while)需要一个相当复杂的“for”条件。这使我们回到了布尔绝对值:条件必须评估为真或假。

因此,虽然我无法想象编译器无法被操纵以执行正确逻辑的情况,但我可以在很短的时间内看到任何维护您的程序的人都可能希望您被扔石头(或者可能认为您已经被扔了)。

在相关说明中,您可以在 Java 中做任何机器语言无法完成的事情。但是有很多非常好的理由不使用机器语言。当您尝试“可爱”地编写代码时,它们中的大多数同样适用。在您与 0300 的愤怒客户或您的老板或两者通电话之前,一切都是有趣和游戏。

于 2013-10-09T17:36:16.467 回答