CodingBat Java help pages:
If and Boolean | Java Strings | While and For Loops | Arrays and Loops |
A while loop has a boolean test and a body containing statements, like this:
int count = 0; while (count < 100) { // test: boolean test within (..) System.out.println("count:" + count); // body: statements within {..} count = count + 1; } System.out.println("all done!");An if-statement looks at the test one time and then maybe executes the body once. The while-loop extends this idea, executing the body again and again, checking the test each time. The while-loop follows these steps:
count:0 count:1 count:2 count:3 ... count:98 count:99 all done!The count variable starts at 0, and increases by 1 on each iteration. On the 100th iteration of the loop body, the body prints "99" and then increases count to 100. The program loops back to the top and checks the test (count < 100) again. On all previous checks, the test was true. This time the test is false, and the loop exits without executing the body. We use while-loops to execute some code until some condition is satisfied.
// Given a num, returns how many times can we divide it by 2 to get down to 1. int count2Div(int num) { int count = 0; // count how many divisions we've done while (num >= 1) { num = num / 2; count++; } return count; }
int count = 100; while (count < 100) { // the test is false the very first time count = count + 1 // this line never runs }
int count = 0; while (count < 100) { System.out.println("count:" + count); count = count * 1; // OOPS, does not change count }Or suppose we forget to put in the count line entirely, so the loop just spins in place with count stuck at zero:
int count = 0; while (count < 100) { System.out.println("count:" + count); // OOPS, forget to put in a line that changes count at all }Prints when run:
count:0 count:0 count:0 count:0 ... --never stops--In some cases, we want the code to run on and on without stopping. In that case, we might write an infinite loop on purpose by giving true as the test:
while (true) { // deliberate infinite loop ... ... }
Many computer people like to think of themselves as part of a whimsical field that does not take itself too seriously compared to more established disciplines. For example, Apple Computer headquarters is located on "1 Infinite Loop, Cupertino CA".
For example, suppose we have a Frog object that responds to dive() and float() methods that move the frog around in a pond. The frog also responds to an isSunny() method that returns true if the frog is in the sun. We want to write a "find sun" loop that does this: float, check if there is sun. If there is sun, we're done. Otherwise, dive and try the cycle again. So the sequence is float, sun check, dive, float, sun check, dive, .... until the sun check returns true. The key feature here is that the test does not naturally fit at the top of the loop. Instead the test most cleanly goes in the middle of the loop.
The code for this problem demonstrates uses an while-break structure. An if statement in the middle of the while loop checks for the exit condition. If the exit condition is true, the code calls "break" which exits the while loop immediately:
// suppose we have a variable "frog" while (true) { // use "true" as test -- exit is handled by the if-break below frog.float(); // Exit using if-break // Check for exit condition, and if true call break if (frog.isSunny()) { break; // this exits the loop } frog.dive(); } // The break exits the loop, leading to this lineWith the while-break, we have the power of a while loop, but now we can position the test anywhere we want instead of just at the top. In fact, a standard while loop of this form:
while (test) { body }Is equivalent to a while-break loop where the break is positioned at the very top:
while (true) { if (!(test)) { break; } body }As a matter of good coding style, we would not write a loop using while-break unless there was no other way. The standard while loop is shorter, more readable, and can express what we want 90% of the time. We use the while-break version where necessary to deal with cases where the test does not go at the top.
Notice that the normal while loop test is a "green light" condition -- if it is true, the loop continues; if it is false the loop exits. With a while-break, the test is the opposite. The while-break test is a "red light" condition. If it is true, the loop exits.
for (int i=0; i<100; i++) { System.out.println("i:" + i); }This loop prints:
i:0 i:1 i:2 i:3 i:4 ... i:99The for-loop has four parts -- init, test, increment, and body -- separated by semi-colons (;)
for ( init ; test ; increment ) { body }The for-loop is used specifically to step a variable through a sequence of values, such as 0, 1, 2, 3, .. 99. In fact, most for-loops adhere to that pattern so closely, that they will look similar to the 0..99 for-loop code above.
The for-loop follows four steps:
It is idiomatic to use the variable name "i" for a counter variable. Although we avoid single-letter variable names for general purpose storage, this use of "i" is standard in a for-loop like this. Indeed, this pattern is so standard that other programmers would likely be a little confused if you used a variable name other than "i" in a for-loop. The convention extends to using the names "j", and "k" for loop variables if "i" is already in use. Never use lowercase L "l", since it looks just like the digit one "1" in many fonts.
In this case, the increment is "i++" which increments the variable "i" by one. Since "i" is the common variable choice for a for-loop, it is very common for the increment to be "i++". It is idiomatic to write the increment as "i++" as opposed to the similar "i = i + 1".
/* Classic for-loop counting up from 0 to 99 0, 1, 2, 3, ... 99 -init int i = 0 -test i<100 -increment i++ */ for (int i=0; i<100; i++) { System.out.println(i); } /* For-loop to print the values 0, 2, 4, 6, .. 98 -increment by i+=2, instead of i++ (same as i = i + 2) */ for (int i=0; i<100; i+=2) { System.out.println(i); } /* For-loop from 99 down to 0 99, 98, 97, ... 0 -init i=99 -test i>=0 -increment i-- */ for (int i=99; i>=0; i--) { System.out.println(i); } /* For-loop from 0 to 100 by 5's 0, 5, 10, 15, .. 100 -test i<=100 -increment i+=5 */ for (int i=0; i<=100; i+=5) { System.out.println(i); }
init while (test) { body increment }So for example, we could write the standard 0..99 loop like this, although for real code we would prefer the for-loop in this problem:
int i = 0; while (i<100) { System.out.println(i); i++; }As a matter of style, if we are solving a series-of-values 0, 1, 2, 3, ... 100 type problem, then the for-loop is preferable. That's exactly what it does. If the looping problem does not fit into the series-of-values pattern, then the standard while-loop is best.
public int findCode(Vault vault) { for (int i=0; i<=1000000; i++) { if (vault.tryCode(i)) { // found the code! return(i); } } return(-1); // if we get here, we did not find the code }So in this case, reaching 1 million is one exit condition, and tryCode() returning true is the other.
count = 0; while (count < 100) { count = count + 10; count = count - 10; count = count + 1; }This loop changes count up and down inside the loop. For example, at some point we imagine that the line "count = count + 10" will make the test (count < 100) false. However, that will not exit the loop, because the test is not checked at that time. The test is only checked at the very top of the loop, just before each run of the body. So in this strange example, there will be times that count is greater than 100, and the loop will continue to run, exiting only when count is >= 100 at the top of the loop.
CodingBat.com code practice. Copyright 2010 Nick Parlante.