Reputation: 326
This is a long running debate between me and my teacher. Can there be a situation where a for
loop absolutely cannot be used in place of a while
/do
-while
loop? In other words, is there a specific case where a for
-loop will not work in place of a while
loop; is while
/do
-while
in any way "distinct" from for
?
Upvotes: 23
Views: 2330
Reputation: 129507
No, there is no such situation. Every do
-while
loop can be written in terms of a while
-loop (by executing the body once before the loop) and vice versa. In turn, every while
-loop
while (X) {
...
}
can be written as
for (; X;) {
...
}
i.e. we omit an initialization and an increment statement. We can also convert from a for
back to a while
by correctly placing the initialization and increment.
In short, it's always possible to convert from one loop variant to either of the other two. for
-loops just give you the benefit of being able to limit the scope of a loop control variable and do any incrementation at the top. It goes without saying that in many cases one particular loop variant makes much more sense to use than the others; each has its specific use cases.
Also note that the fun doesn't just end with loops: it's also possible to convert every loop into a recursive function and vice versa (although in practice there could be limitations to this; for example a loop that worked fine could, when converted to a recursive function, produce a stack overflow error).
[I]s
while
/do
-while
in any way "distinct" fromfor
?
It is not. For instance, the bytecode of the following two snippets is identical:
int x = 0;
while (x < 10) {
x++;
}
and
int x = 0;
for (; x < 10;) { // or: for (; x < 10; x++) {}
x++;
}
both become:
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
There was talk in the comments about for
-each loops and that they might be intrinsically different from the other loop types. This is absolutely not true; for
-each loops are pure syntactic sugar around iterators (or looping over arrays). Every for
-each loop can also be converted to each of the other loop types. Here's an example:
for (String s : l) { // l is a list of strings
System.out.println(s);
}
and
String s;
Iterator<String> iter = l.iterator(); // l is a list of strings
while (iter.hasNext()) {
s = iter.next();
System.out.println(s);
}
both become:
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
Upvotes: 37
Reputation: 142921
The other answers have already covered the equivalence between a while
loop and a for
loop. That is,
while(<expr>) {
<body>
}
is equivalent to
for(;<expr>;) {
}
Note that a similar reduction can be done with a do
-while
loop. Any do
-while
loop
do {
<body>
} while(<expr>);
is functionally equivalent to
for (boolean firstIter = true; firstIter || <expr>; firstIter = false) {
<body>
}
Upvotes: 2
Reputation: 13097
No, you can always rewrite a for loop as a while loop, and any while look as a for loop.
<init>
while (condition) {
...
<increment>
}
is equivalent to:
for (<init>; <condition>; <increment>) {
...
}
Upvotes: 6
Reputation: 927
"Absolutely"? I'd say no. However a test after loop aka do-while in Java would require a pretty convoluted "for" condition. Which brings one back to the boolean absolute: the condition must evaluate true or false.
So while I cannot envisage a case when the compiler could not be manipulated into performing the correct logic, I can see in very short order where anyone maintaining your program might well want you stoned (or perhaps think you were already).
On a related note there is nothing you can do in Java that cannot be done in machine language. But there are lots and lots of really good reasons for not using machine language. Most of them apply equally for when you try to get "cute" writing your code. It's all fun and games until you're on the phone with an irate customer at 0300, or your boss, or both.
Upvotes: 0