Loops
Objective #1: Explain the importance of loops in programs.
- In order to write a non-trivial computer program, you almost always need to use one or more loops. Loops allow your program to repeat groups of statements a specified number of times. Loops are classified as a type of iteration (or repetition) structure.
- It is important to be aware of how many iterations a given loop is expected to perform. If a loop does not iterate a finite number of times, it is considered to be an infinite loop. Rarely would a programmer ever intentionally incorporate an infinite loop into a program, however it is easy to do so by mistake.
- It is important to write out and trace loops carefully to avoid an off-by-one bug (OBOB). An off-by-one bug is a logic mistake caused by a loop iterating one extra time.
Objective #2: Use for loops.
- A for loop always executes a specific number of iterations. Use a for loop when you know exactly how many times a set of statements must be repeated.
- A for loop is called a determinate or definite loop because the programmer knows exactly how many times it will iterate. You can mathematically determine the number of iterations by deskchecking the logic of the loop.
- After the keyword, for, a set of parentheses is necessary with three expressions as parameters.
for(initializing expression; control expression; step expression)
{
one or more statements
}
- The initializing expression sets the counter variable for the loop to its initial value.
- The control expression ends the loop at the specified moment.
- The step expression (or incrementing expression) changes the counter variable,effectively determining the number of iterations. The counter variable often increments by one, but it may increment, decrement, or count in other ways.
- The one or more statements in the curly braces is the body of the loop
- Example:
for (i = 1; i <= 3; i++)
{
System.out.println(i);
}
- It is possible to initialize the loop variable within the initializing expression as in:
for (int i = 0; i < 10; i++)
{
System.out.println(i);
}
However the scope of i is
the loop and i cannot
be used outside of the loop even if the loop is written without curly braces.
Note the compile error that occurs in the following example,
for (int i = 0; i < 10; i++)
{
System.out.println(i);
}
System.out.println(i);
// causes compile error since i was declared inside the for loop, its scope is limited to the body of the for loop and it cannot be used or referenced outside of the for loop.
In fact,
curly braces can be used to narrow the scope of a variable in non-loop situations.
In this example,
int outside = 5;
{
int inside = outside;
}
outside = inside;
an error occurs since the variable inside cannot
be used outside of the set of curly braces. Since inside is
declared inside of
the curly braces, its scope
is only the area within the curly braces.
- You can increment the loop variable by more than 1 if you wish. In the following loop, the loop variable is incremented by 3 on each iteration:
for (i = 1; i <= 9; i = i + 3)
{
System.out.println(i);
}
Of course, the compound operator could be used with i += 3 replacing the i = i + 3 incrementing expression as in this valid example
for (i = 1; i <= 9; i += 3)
{
System.out.println(i);
}
It is a common error for students to mistakenly use:
for (i = 1; i <= 9 ; i + 3)
instead of the required
for (i = 1; i <= 9; i = i + 3)
- Some programmers use a for loop like,
for (;;)
{
System.out.println("Enter a number: ");
//user inputs a value into userInput w/ JOptionPane or BufferedReader
if (userInput != -99)
{
runningTotal += userInput;
}
else
{
break;
}
}
in which case the infinite for loop will run until the break condition is met. Note that technically the initializing, control, and incrementing expressions of a for loop are optional. However, this is poor coding since it can lead to logical errors and generally you should avoid using break statements and infinite loops when possible. A while loop may be a better and safer choice than a for loop in these situations.
- Another variation of a for loop that you are unlikely to see in this course or on the AP Computer Science exam is one that uses two (or more loop control variables). It is possible to place two initializing expressions or two incrementing expressions in a for loop as long as a comma is used to separate them. Here is an example,
for (int i = 0, j = 10; i < 5 && j > 5; i++, j--)
{
System.out.println(i + " + " + j + " = 10");
}
which displays
0 + 10 = 10
1 + 9 = 10
2 + 8 = 10
3 + 7 = 10
4 + 6 = 10
Both i and j are declared as integers and initialized in the loop's initializing expression. They are both modified in the step expression and they are both used in the control expression.
- Like if statements and other kinds of loops, the curly braces are not required with a for loop if there is only statement in the body of the loop. However, it is good style to always use curly braces. Review the following valid and invalid examples
for (int i = 0; i < 5; i++);
{
System.out.println("hello world");
}
only displays hello world one time since the extra semicolon is treated as the body of the loop.
What displays due to the following code segment?
for (int i = 0; i < 5; i++) System.out.println("hello"); System.out.println("goodbye");
Answer:
hello
hello
hello
hello
hello
goodbye
since the goodbye statement is not considered to be inside the body of the loop!
- This following examples compile and each display hello world five times even though each one is typed with poor, obfuscated style:
for (int i = 0; i < 5; i++) System.out.println("hello world"); // one line of code
for (int i = 0; i < 5; i++)
System.out.println("hello world"); // body statement is not indented
for(int i=0;i<5;i++) // cramped spacing
System.out.println("hello world");
for(int i = 0; i < 5; ) // incrementing expression is placed in the body of the loop
{
System.out.println("hello world");
i++;
}
int i = 0;
for( ; i < 5; i++) // initializing expression is placed before & outside of the loop
{
System.out.println("hello world");
}
int i = 0;
for( ; i < 5; ) // initializing & incrementing expressions placed incorrectly.
//
You may as well use a while loop
{
System.out.println("hello world");
i++;
}
Objective #3: Use while loops.
Objective #4: Use the break and continue statements with loops appropriately.
- A break statement is used to stop the execution of a loop immediately and to continue by executing the statement that comes directly after the loop. Only use the break statement when it is not practical to control the execution of a loop with its control expression. That is, only use a break statement when absolutely necessary.
while (num != -99)
{
user inputs a value for num here
if (num == -99)
{
break;
}
sum += num;
}
however it would be better to write this loop to avoid the use of a break statement if possible since break statements found within a loop can be difficult to pick out by those who read over your code. This version of the same loop would be better for clarity.
num = 0;
while (num != -99)
{
sum += num;
user inputs a value for num here
}
- A continue statement is used to stop the execution of the statements in the loop's body on that particular iteration and to continue by starting the next iteration of the loop.
In the following example, all inputed positive numbers less than or equal to 100 are subtotaled. If a negative value is inputed, it is not added to the subtotal but rather the loop continues with the next iteration. Any value greater than 100 could be entered to terminate the loop.
while (num <= 100)
{
user inputs a value for num here
if (num < 0)
{
continue;
}
sum += num;
}
Objective #5: Use nested loops effectively when appropriate.
- A loop of any kind may be placed in another loop (of any kind). One must be sure though to entirely encapsulate the inner loop inside of the outer loop, otherwise an error is sure to occur. Two loops are considered to be nested loops if one is enclosed within the other.
- Example:
for (i = 0; i <= 10; i++ )
{
System.out.println("i is " + i);
for (j = 10; j >= 0; j-- )
{
System.out.println("j is " + j);
}
}
- Example:
int row = 0;
while (row < 4)
{
int col = 0;
while (col < 4)
{
System.out.print("*");
col++;
}
System.out.println();
row++;
}
Objective #6: Use flag variables and sentinel values to control indeterminate loops.
- A sentinel value is a special value that is used to cause an indeterminant loop to terminate. Often sentinel values are inputed by a user to indicate the end of input. For example, the sentinel value of -99 is used in the loop below to terminate the loop which calculates a bowling average. It should be noted that the -99 is being used as a sentinel value since it is impossible in the sport of bowling to bowl a score of -99. Therefore the sentinel value will not mistakenly be entered as an inputed bowling score.
System.out.println("Enter a bowling score (-99 to quit): ");
user inputs a value for score here
while (score != -99)
{
sum += score;
numGames++;
System.out.println("Enter a bowling score (-99 to quit): ");
user inputs a value for score here
}
System.out.println("Your average is " + (double) sum / numGames);
- A flag variable is a special variable that is used to control an indeterminate loop. A flag variable is usually a boolean variable that is assigned true or false. Some old-fashioned programmers use an int variable and use the value 1 for true and 0 for false.
boolean exit = false;
while (!exit)
{
System.out.println("1 Book");
System.out.println("2 CD");
System.out.println("3 Exit");
System.out.println("Enter a menu option: ");
user inputs a value for menuChoice here
if (menuChoice == 1)
{
System.out.println("You ordered another book.");
numBooks++;
}
else if (menuChoice == 2)
{
System.out.println("You ordered another cd.");
numCDs++
}
else if (menuChoice == 3)
{
exit = true;
}
}
Objective #7: Identify loop invariants.
- A loop invariant is an expression
that is always true at the top of a loop. It is an expression that is true
every time the loop iterates including the last time around the loop even
when
the
loop's
control expression is false and the loop terminates.
- Consider the loop
int sum = 10;
for (int i = 2; i < 12; i += 2)
{
System.out.println(i);
sum += i;
}
The following are loop invariants for the loop above:
i is always even
i <= 12
i is positive
sum > i
The following is not a loop invariant:
i < 12 since i is equal to 12 on the last attempted
iteration
- Another example...
int temp = 0;
int num = 1;
while (num < 100)
{
num += 2;
System.out.println(num);
temp = num;
num = -5;
num = temp;
}
The following are loop invariants in the code segment above:
num is always odd
num < 102
num > -6
num > 0 (since num is greater than zero every
time the computer is at the top
of the loop, even on the last iteration)
The following is not a loop invariant:
num < 100 (since num is 101 on the last evaluation of the control expression
when it evaluates to false)
You will not be tested on any material below this sentence in the lecture notes. However, the information is useful for serious, advanced students.
Objective #8: Use do while loops.
- AP students are not required to be able to write or evaluate do while loops on the AP exam. However they can be used in a student's answer on the Free Response section of the exam.
- As with a while loop, a do while loop does not necessarily iterate a specified number of times. However, it is guaranteed that a do while loop will iterate at least one time because its control expression is placed at the end of the loop. This loop is useful when you want to guarantee at least one iteration of the loop.
- Like a while loop, a do while loop is considered to be an indeterminate or indefinite loop.
- A do while loop is considered to be a bottom-checking (or posttest) loop, since the control expression is located after the body of the loop after the while keyword. A do while loop is guaranteed to iterate at least once even if the control expression evaluates to FALSE.