这是我和我的老师之间长期争论的一个问题。是否存在一种情况,for
循环绝对不能用来替代while
/do
-while
循环?换句话说,是否存在一种特定情况,在该情况下for
循环无法取代while
循环;while
/do
-while
是否以任何方式与for
不同?
这是我和我的老师之间长期争论的一个问题。是否存在一种情况,for
循环绝对不能用来替代while
/do
-while
循环?换句话说,是否存在一种特定情况,在该情况下for
循环无法取代while
循环;while
/do
-while
是否以任何方式与for
不同?
while (X) {
...
}
for (; X;) {
...
}
for
循环转换为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
for
和 while
循环只是在条件跳转周围添加的语法糖! - chrylis -cautiouslyoptimistic-if<cond>
,而在x86中,它是J*
操作码。循环是由编译器管理的跳转模板实现的。 - chrylis -cautiouslyoptimistic-javap
程序,特别是 -c
选项。 - chrylis -cautiouslyoptimistic-for (; checkIsTrue; ) { ... }
,而应该使用while (checkIsTrue) { ... }
。” - Andrew Coonce<init>
while (condition) {
...
<increment>
}
等价于:
for (<init>; <condition>; <increment>) {
...
}
<init>
包含需要调用函数、声明多个不同变量或实例化类的几行代码,那该怎么办呢?我能想到的唯一限制是你可能无法在for
循环的<init>
部分放置任何想要的内容。(虽然你可以将该部分放在for
循环之前并在内部省略它,但我不知道这是否算数 :)) - Spookwhile(<expr>) {
<body>
}
等同于
for(;<expr>;) {
}
do
-while
循环也可以实现类似的简化。任何do
-while
循环都可以。do {
<body>
} while(<expr>);
与...在功能上等价
for (boolean firstIter = true; firstIter || <expr>; firstIter = false) {
<body>
}
firstIter
已经存在并且在<body>
和/或<expr>
中被使用,否则此方法将失败。 - Joseph Quinsey“绝对”?我会说不是。然而,在Java中,循环后的测试(即do-while)需要一个相当复杂的“for”条件。这就让人回到了布尔绝对值:条件必须评估为真或假。
因此,虽然我无法想象编译器不能被操纵以执行正确逻辑的情况,但我可以很快看出,任何维护您程序的人都可能希望你被石头砸死(或者认为你已经被砸死了)。
在相关的注释中,Java中没有什么是不能用机器语言完成的。但是,有很多非常好的理由不使用机器语言。大多数原因同样适用于当您尝试“聪明地”编写代码时。这一切都很有趣,直到您在凌晨3点接到愤怒的客户电话,或者您的老板打来电话。
if
语句和递归。 - Raedwald