Schedule‎ > ‎

### Lesson 5: Getting Loopy

#### Review Question

• What is displayed by running the following code snippet?
```bool bb;
if (bb || !bb) {
cout << "That is the question!";
}
```
1. That is the question!
2. Nothing
3. Does not compile
4. Compiles but causes an error when it runs

## 5.1: Counting Loops

Learner Outcomes
 At the end of the lesson the student will be able to:Design and implement counting loopsApply counting loops to solve a number of problemsTranslate these designs into C++ code

### 5.1.1: Using Loops to Count

• Counting is a way to solve many programming problems
• As an example, assume we want a program to write a list of numbers
• We want to start at the number `1` and let the user choose the ending number
• Thus the program output will look something like:
```This program writes lists of numbers.
Enter the maximum number: 5
1
2
3
4
5
```
• We cannot simply print five numbers with `cout` because the user chooses the maximum number
• Since we understand our problem, our next step is to write our algorithm
• To help us understand the algorithm we try out some counting examples

#### Activity: Exploring the Problem

• Clap your hands 5 times.
• True or false: as you are clapping, you are repeating an action.
• You know when to stop clapping because you ________.
• True or false: as you are counting, you are testing the count against the number 5.
• Every time you clap, you update the count by ________.

#### Developing the Algorithm

• As we are clapping our hands, we are repeating an action
• In C++, the control structure we have learned for repeating commands is the ________
• To have a computer remember a number for the count, we declare a ________
• After we declare a variable for counting, an appropriate initial value is ________
• The while loop has a test condition as part of its syntax
```while (test) {
statement1
statement2
...
}
```
• If the count started at one, an appropriate test condition for the while loop to end after 5 iterations is ________
• Every time we clapped our hands, we increase the count by one
• A C++ statement to increase the count by one is ________
• Thus for counting to 5, we have a series of commands like:
```int counter = 1;
while (counter <= 5) {
cout << counter << endl;
counter++;
}
```
• If we allow the user to choose the ending number, what change do we make to the above loop?

#### Example C++ Application That Counts to a Number

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ``` ```#include using namespace std; int main() { int max = 0; cout << "This program writes lists of numbers.\n"; cout << "Enter the maximum number: "; cin >> max; int counter = 1; // initialization code (1) while (counter <= max) // loop condition (2) { // loop body (3) cout << counter << endl; counter++; // update the counter (4) } return 0; } ```
• Notice there are four parts to a counting loop:
1. initialization statement
2. test condition
3. loop body containing statement to repeat
4. update statement
• We need to remember these four parts when designing a counting loop

#### Difference Between Declaration and Initialization

• Declaration means to set aside memory space
```int counter;
```
• Initialization means set a value appropriate to the start of an operation
```counter = 1;
```
• We often both declare and initialize a variable in one statement like:
```int counter = 1;
```

#### Check Yourself

1. For the example loop shown below, the loop displays the numbers: ________.
```int counter = 1; // counter variable initialization
while (counter <= 3) { // test condition
//loop body containing statements to repeat
cout << counter << endl;
counter = counter + 1; // update statement
}
```
2. True or false: the purpose of the variable `counter` is to keep track of the number of repetitions.
3. True or false: if `counter` started at 100 (`counter = 100`), the loop would never repeat.
4. True or false: if the statement updating the count was omitted, like in the code shown below, the loop would never stop repeating until the program was terminated.
```int counter = 1; // counter variable initialization
while (counter <= 5) { // test condition
//loop body containing statements to repeat
cout << counter << endl;
}
```

### 5.1.2: Introducing `for` Statements

• It turns out that counting is a very common way to use loops
• Loops that are controlled by a counter variable are called counter-controlled loops
• We can visualize a counter-controlled loop as a series of steps to reach a goal
• A counter-controlled loop has the form:
```i = start;
while (i < end) {
...
i++;
}
```
• Where:
• i: the name of a counter variable
• start: the initial starting count
• end: the final ending count
• Because counting loops are so common, there is a special statement:
```for (i = start; i < end; i++) {
...
}
```
• The following example shows the same loop as before but using a `for` loop instead of a `while` loop
• Note how the repeated code is indented inside the loop
• This lets us see easily which code is repeated and which is not

#### Execution Steps

1. When `for` loop is reached, execute the `initialize` statement (example: `int i = 1;`)
2. Check if `condition` is `true` (example: `i <= max`;)
1. if `true` then continue with Step 3
2. Otherwise it is `false` so continue with Step 6
3. Execute the block containing the statements to repeat (body)
4. When end of loop body is reached, execute the `update` statement (example: `i = i + 1`)
6. Loop is finished: continue with statements after the loop

### Exercise 5.1a: First `for`-Loop (5m)

In this exercise we write our first `for`-loop.

1. Copy the following program into a text editor, save it as `forloop.cpp`, and then compile and run the starter program to make sure you copied it correctly.
```#include <iostream>
using namespace std;

int main() {

return 0;
}
```
2. Add the following code to get the maximum number from the user:
```int max = 0;
cout << "This program writes lists of numbers.\n";
cout << "Enter the maximum number: ";
cin >> max;
```
3. Add the following `for`-loop code to the `main()` function.
```cout << "for loop:\n";
for (int i = 0; i < max; i++) {
}
```
4. Compile and run your code to verify it works. Does it start and stop with the correct numbers?
5. Save your final `counting.cpp` file.
6. Be prepared to answer the following Check Yourself questions when called upon.

#### Check Yourself

Note: this loop is different than the previous exercise.

1. In the loop above, the initialization statement is ________.
1. `int i = 1`
2. `i <= max`
3. `i++`
4. `cout << i << endl;`
2. For the same loop, the test condition is ________.
1. `int i = 1`
2. `i <= max`
3. `i++`
4. `cout << i << endl;`
3. For the same loop, the update statement is ________.
1. `int i = 1`
2. `i <= max`
3. `i++`
4. `cout << i << endl;`
4. For the same loop, if the user enters 3 the values printed are ________.
1. 0, 1, 2, 3, 4
2. 1, 2, 3, 4
3. 0, 1, 2, 3
4. 1, 2, 3
5. For the same loop, if the user enters 3 the values of the counting variable `i` are ________.
1. 0, 1, 2, 3, 4
2. 1, 2, 3, 4
3. 0, 1, 2, 3
4. 1, 2, 3

### 5.1.3: Summing Numbers

• One common looping task is to sum a series of numbers and calculate their sum
• This is a mathematical operation known as summation

• For example, if we want to add the sum of the first four integers:
`sum = 1 + 2 + 3 + 4 = 10`
• As another example, we can add a list of 5 numbers:
`sum = 1 + 2 + 3 + 4 + 5 = 15`
• We want the user to specify n, which is the ending number

#### Developing the Algorithm

• Looking at the examples above, what characteristics do we notice?
• Do we see repetition? (Yes / No)
• Whenever we need to sum a list of numbers, coding a loop is a good approach
• For our loop we need to consider four parts:
1. initialization statement
2. test condition
3. loop body containing statement to repeat
4. update statement
• In addition, we need to ask the user for n, the ending number
• Thus our algorithm looks like:
```Prompt the user
Get the ending number
sum = 0
for (int i = 1; i <= ending number; i++)
sum = sum + i
```
• Notice that we have a separate variable to store the sum
```sum = 0;
```
• We need two variables in a summation loop
• `i`: the counter variable to store the current count
• `sum`: the variable to store the sum of the numbers

#### Example Application to Sum a Sequence of Numbers

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ``` ```#include using namespace std; int main() { cout << "Enter the number to sum to: "; int endN = 0; cin >> endN; int sum = 0; for (int i = 1; i <= endN; i++) { sum = sum + i; } cout << "Total sum = " << sum << endl; return 0; } ```

#### Variations

• Sometimes we only want to sum part of the numbers in a loop
• We can adjust the summing loop to read a different quantity of readings by changing the starting or ending value
• For example, if we wanted to skip the first value we would change the for-loop like:
```for (int i = 2; i <= endN; i++)
```
• We could change the summing loop to read every other value by changing the update statement like:
```for (int i = 2; i <= endN; i += 2)
```
• What numbers does the above loop tally?
• The starting value can have a significant effect on the loop
```for (int i = 1; i <= endN; i += 2)
```
• What numbers does the above loop tally?

Be the computer

#### Tracing a Loop

• To understand what is happening with these loops it is important to trace iterations
• In essence, we must "be the computer" and follow it execution path
• The counting variable is used by the computer to track the number of iterations
• Thus a good technique is to keep track of the counting variable to understand the loop
• In addition, we want to keep track of any other variable processed inside the loop
• For example, with the following loop we would want to track the variables: sum, i, and reading:
```double sum = 0.0;
for (int i = 0; i < 5; i++) {
sum = sum + i;
}
```
• Thus we would write out headings for each value and update the variables for each pass of the loop
```sum   i
---   -
0     0
0     1
1     2
...
```

#### Try It: Tracing a Loop (4m)

In this activity, we manually trace the execution of the following summing loop. This is a different loop than the previous examples.

```const int END = 10;
int sum = 0;
for (int i = 1; i <= END; i += 2) {
sum = sum + i;
}
```
1. Take out a piece of paper and put your name on the paper.
2. On the paper, add two columns for the two variables:
```sum     i
---     -
```
3. Under each column, write the value of the `sum` followed by counter variable `i` that would be present when the test condition is checked for each iteration of the summing loop, like:
```sum     i
---     -
0       1
1       3
(next pair of values)
(next pair of values)
...
```

Place each pair of values on a new line.

4. Save your paper for a later exercise.
5. Be prepared to answer the following Check Yourself questions when called upon.

#### Check Yourself

```int sum = 0;
for (int i = 1; i <= 5; i++) {
sum = sum + i;
}
```
1. True or false: summing numbers in a loop requires a dedicated variable to store the sum.
2. In the above loop, to sum even numbers only we would change the ________ statement.
3. To sum odd numbers only, we would additionally change the initialization statement to start at ________.
4. To compute the product of the numbers, we would change the update statement to use the operator ________?

### 5.1.4: Summing and Averaging

• We have looked at adding the counter each time through a loop
• Instead of just adding the counter each time, we can ask the user for each number and add it to the sum, like:
```sum = 0
cin >> number;
sum += number;
cin >> number
sum += number
repeat for n numbers
```
• We want to be able to sum any list of numbers
• Whenever we need to sum a list of numbers, coding a loop is a good approach
• If we know the number of inputs in advance, we can use a counting loop
```cout << "Enter the quantity of numbers: ";
cin >> qty;
for (int i = 1; i <= qty; i++)
```
• Inside the loop we ask for each value and add it to the sum
```cout << "Enter value #" << i << ": ";
double value;
cin >> value;
sum = sum + value;
```

#### Example Application to Sum a Series of Numbers Entered by a User

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ``` ```#include using namespace std; int main() { cout << "Enter the quantity of numbers: "; int qty = 0; cin >> qty; double sum = 0; for (int i = 0; i < qty; i++) { cout << "Enter value #" << (i + 1) << ": "; double value; cin >> value; sum = sum + value; } cout << "Total sum = " << sum << endl; return 0; } ```

#### Calculating the Average

• One we have the sum, we can calculate the average of a group of numbers
• By average, we are referring to the statistical mean
• To find a mean, we adding up the values and then divide by the number of values, like:
```cout << "Average = " << sum / qty << endl;
```

#### Check Yourself

```double sum = 0;
for (int i = 1; i <= 5; i++) {
cout << "Enter value #" << (i + 1) << ": ";
double value;
cin >> value;
sum = sum + value;
}
```
1. In the above loop, if the user enters the numbers 1, 2, 3, 4, 5 the value of `sum` after the loop finishes executing the sum is ________.
2. After the above loop completes, the correct statement to average the input is ________.
1. `int average = sum * 5;`
2. `double average = sum / 5;`
3. `int average = sum / 5.0;`
4. `double average = sum * 5.0;`
3. True or false: if `sum` was declared as an `int`, an `average` would still be accurate because decimals have little value.

### 5.1.5: More Loopy Errors

• A common problem with counting loops is the off-by-one error
• Finding the correct upper and lower bounds can be confusing
• Should we start at 0 or 1?
• Should we use `<` or `<=` as the test condition?
• To understand the counting loop we need to count iterations
• For instance, the following loop executes b - a times:
`for (int i = a; i < b; i++)`
• However, the following loop is executed b - a + 1 times:
`for (int i = a; i <= b; i++)`
• The "+1" is the source of many errors
• As a test, to sum the numbers from 1 to 5 what is wrong with:
```#include <iostream>
using namespace std;

int main()
{
int sum = 0;
for (int count = 0; count < 5; count++)
{
sum += count;
}
cout << sum << endl;

return 0;
}
```
• One way to visualize the "+1" error is by looking at a fence

• How many posts do we need for a fence with three sections? (answer)
• It is easy to be "off-by-one" with problems like this
• Forgetting to count the last value is sometimes called a fence-post error

#### Debugging Technique: Tracing Variables

• One good way to discover loopy errors is to display the variables that are part of the loop
• Tracing variables means watching their values change as the program executes
• We can insert temporary output statements in a program to watch the variables, like:
`cout << "count=" << count << ", sum=" << sum << endl;`

#### Check Yourself

1. True or false: to avoid off-by-one errors, you need to count iterations.
2. For three sections of fence you need ________ posts.
3. The following loop executes ________ times.
```for (int i = a; i < b; i++)
```
1. `b + a`
2. `b - a`
3. `b - a + 1`
4. `b - a - 1`

### Exercise 5.1: Count Down (5m)

In this exercise we continue exploring uses of counter-controlled loops.

Imagine we are at NASA Mission Control and a new space ship is about to be launched. We are going to write a program to count down from 10 to liftoff like this example.

```NASA Mission Control readying for liftoff.
Initializing countdown from 10...
10
9
8
7
6
5
4
3
2
1
We have liftoff!
```

Thus we will need our loop to count down rather than up.

#### Specifications

1. Copy the following program into a text editor, save it as countdown.cpp, and then compile and run the starter program to make sure you copied it correctly.
```#include <iostream>
using namespace std;

int main() {

return 0;
}
```
2. In your `countdown.cpp` file, add a statement in main() like:
```cout << "\nNASA Mission Control readying for liftoff\n";
```
3. After the above `cout` statement, add other `cout` statements to duplicate the example output:
```NASA Mission Control readying for liftoff.
Initializing countdown from 10...
```
4. After the cout statements, write a for loop that looks like this:
```for (int countdown = 10; test condition here; update statement here) {
// countdown statements here
}
```

What should go inside the test condition?

5. Inside the `for`-loop, add a `cout` statement to print the value of `countdown` on its own line.
6. When the loop is finished, add the final line:
```We have liftoff!
```
7. Save your final `countdown.cpp` file to submit to Canvas in Exercise 5.1.

### 5.1.6: Summary

• Loops allow us to repeat statements in a program
• One common use for loops is to count
• When counting, we need to remember the number of the count
• To remember a value, we use a variable
• Thus, to count, we need both a loop and a counter variable
• The for loop gives us a compact way to code program counter-controlled loops
```           ❶    ⇛    ❷   ⇚   ❸
for (int i = start; i < end; i = i + 1) {
...
}
```
• The `for`-loop executes as shown in the following diagram:

• We saw several applications for loops that count in this section:
• Counting loops
• Summing numbers
• Averaging numbers
• Once we know that a program needs a loop, we need to consider these things:
1. Loop body -- which statements to repeat
2. Loop test condition -- when to loop and when to stop
3. Loop test update -- must change something to exit the loop
4. Initialization code -- how to get started correctly
• The `for` loop lets us specify the last three items inside the `for` statement
• In addition we looked at the off-by-one error
• The off-by-one error occurs when we make a logic error about a boundary condition like the start or end value of a loop

#### Check Yourself

1. What must you always consider when designing a looping algorithm? (5.1.1)
2. What makes a loop a counting loop? (5.1.2)
3. What does the following code display: (5.1.2)
```for (int counter = 0; counter < 0; counter++) {
cout << counter << endl;
}
```
4. What does the following code display: (5.1.2)
```for (int counter = 5; counter > 0; counter--) {
cout << counter << endl;
}
```
5. How do you code a loop to sum numbers? (5.1.3)
6. What is a "fence-post error"? (5.1.5)

## 5.2: Bar Charts and Nested Loops

 Learner OutcomesAt the end of the lesson the student will be able to:Write nested for loopsHand trace the execution of for loops

### 5.2.1: Graphing Bar Charts

• We may use a counting loop to graph a horizontal bar chart
• To make the chart, we display a series of `'*'` characters for the "bar", like:
```cout << '*';
```
• At the end of the bar, after the loop, we print a newline using:
```cout << endl;
```
• he following example prints a single bar for any number entered

#### Example C++ Application That Displays a Bar Chart

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ``` ```#include using namespace std; int main() { int num = 0; cout << "Enter a number and I will show its" << " bar graph.\nEnter your number: "; cin >> num; cout << "\nBar graph:\n"; for (int i = 1; i <= num; i++) { cout << '*'; } cout << endl; return 0; } ```

#### Display Variations (Optional)

• We can alternate the symbols displayed by adding an `if-else` statement inside the `for`-loop
```for (int i = 1; i <= num; i++) {
if ((i % 2) == 0) {
cout << '*';
} else {
cout << '+';
}
}
```
• Remember that the modulus operator is written as `%` in C++
• The expression `i % 2` evaluates to `0` when `i` evenly divides by `2`
• When the remainder of `i / 2`, which is written as `i % 2`, is `0` then `i` evenly divides by `2`
• If we wanted a tick mark to show every 5 characters we would code something like:
```for (int i = 1; i <= num; i++) {
if ((i % 5) == 0) {
cout << '+';
} else {
cout << '*';
}
}
```
• If we wanted a line chart instead of a bar chart, we print a `'*'` character only on the last iteration of the loop
```for (int i = 1; i <= num; i++) {
if (i == num) {
cout << '*';
} else {
cout << ' ';
}
}
```
• Otherwise we print a `' '` (space) character
• Without the `' '` (space) character we would see only a vertical line

#### Check Yourself

1. The modulus operator used to calculate the remainder is ________.
2. The following code snippet displays ________.
```for (int i = 1; i <= 5; i++) {
cout << '*';
}
cout << endl;
```
1. `****`
2. `*****`
3. `******`
4. `*+*+*+`
3. The following code snippet displays ________.
```for (int i = 1; i <= 6; i++) {
if ((i % 2) == 0) {
cout << '+';
} else {
cout << '*';
}
}
cout << endl;
```
1. `*+*+*`
2. `*+*+*+`
3. `+*+*+*`
4. `+*+*+*+`
4. The following code snippet displays ________.
```for (int i = 1; i <= 5; i++) {
if (i == 5) {
cout << '*';
} else {
cout << '.';
}
}
cout << endl;
```
1. `    *`
2. `.....*`
3. `*.*.*`
4. `....*`

• Some looping applications have loops nested within other loops
• For example, we may use a nested loop to print a table of values or draw shapes
• The following example shows a simple table created with nested loops
• Let's follow the execution sequence before running the code

#### Example of Nested Loops

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ``` ```#include using namespace std; int main() { cout << "Outer\tInner\n"; for (int outer = 1; outer < 4; outer++) { for (int inner = 1; inner < 4; inner++) { cout << outer << "\t" << inner << endl; } cout << "\t(End of inner loop)\n"; } cout << "(End of outer loop)\n"; } ```

#### Tracing the Variables

• To understand a looping application, we need to trace the loop by hand
• To trace the loop, write the variables used in the loop as headings across a page
• On the first line under the headings, write the initial values
• Execute the loop 3-5 times and record the values of the variables each time through the loop
• Pay special attention when entering the loop the first time and when ending the loop
• We can slightly modify the computations if it helps to test the loop
• Below is an annotated trace of the variables for the inner and outer loops
• Note that the outer loop changes only after the inner loop is finished
Memory Screen
` outer `` inner `
`  1``  1``1 1`
`  2``1 2`
`  3``1 3`
`  4` (end of inner loop)
`  2``  1``2 1`
`  2``2 2`
`  3``2 3`
`  4` (end of inner loop)
`  3``  1``3 1`
`  2``3 2`
`  3``3 3`
`  4` (end of inner loop)
`  4` (end of outer loop)  `  `

#### Odometer Analogy

• By analogy, nested loops are like an odometer on a car
• The inner loop is like the digit to the right on an odometer
• The numbers to the right loop completely before the number to the left increments by one

#### Check Yourself

1. True or false: a loop can be nested inside another loop.
2. By analogy to an odometer, an inner loop is like the digits to the ________.
3. Every time an outer loop iterates once, an inner loop runs ________.
1. completely
2. incrementally
3. partially
4. twice
4. To trace a counting loop we need to keep track of the ________.
1. counter variable
2. initialization statement
3. test condition
4. update statement

### 5.2.3: Nested Loop Example: Drawing Rectangles

• Remember that we can draw a single bar with a loop:
```for (int col = 1; col <= size; col++)
{
cout << "*";
}
cout << endl; // newline at end of row

```
• If we draw the bar several times, we get a rectangle
• The code for drawing a square consists of two loops, one nested inside the other:
```for (int row = 1; row <= size; row++)
{
for (int col = 1; col <= size; col++)
{
cout << "*";
}
cout << endl; // newline at end of row
}
```
• The code is easier to read from the inside out
• The inner loop draws a line of characters across the screen from left to right
• At the end of the inner loop we print a newline to end the row
• The outer loop controls the number of lines to draw
• Note how the inner loop is indented to make the structure clear
• The inner loop is controlled by the outer loop, which is why it is indented
• The inner loop in turn controls other statements, which ends up indenting yet again
• Whenever we type an opening brace (`{`) we should indent the next character
• Whenever we type a closing brace (`}`) we should remove the indentation (outdent)

#### Example Program to Draw Squares

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ``` ```#include using namespace std; int main() { cout << "I will print squares for you!\n\n"; cout << "Enter the width of the square: "; int size; cin >> size; for (int row = 1; row <= size; row++) { for (int col = 1; col <= size; col++) { cout << "*"; } cout << endl; // newline before next row } return 0; } ```
• We can make the square hollow by using an `if` statement inside the inner loop to decide when to print characters
• We need a test condition that allows the characters to print only at the start and end of the columns and rows
```if (col == 1 or col == size) {
cout << "*";
} else {
cout << " ";
}
```
• The `else` clause, executed when not printing a letter, prints a space
• Another example of a nested loop is to draw a triangle, which we explore in the next exercise

#### Check Yourself

1. True or false: it is often easier to read nested loops from the inside out.
2. True or false: in the following code, the `endl` is printed every time the inner loop iterates.
```for (int row = 1; row <= size; row++)
{
for (int col = 1; col <= size; col++)
{
cout << "*";
}
cout << endl;
}
```
3. To make a hollow square with the above code, add a(n) ________ to test when to print.

### Exercise 5.2: Tracing Nested Loops (10m)

In this exercise we explore how nested loops work by tracing the execution of a loop in a program. Part of the trace will involve use of the Boolean "or" (`||`) operator we discussed in lesson 4.2.6.

#### Specifications

1. Use your paper from the last paper exercise, make sure your name on it and draw a grid like this:

rowcol#12345
11 21*
21 2 32**
3
4
5

Leave extra room for the `col` column as shown. The right hand area is for drawing the shape where the row and column headings match the `row` and `col` variables of the program.

2. For the code snippet listed below, trace the loop variables and write the values of the loop variables on the paper as your trace progresses for 5 rows. In addition, draw on your paper the shape printed by the nested loops in the program. Do NOT run the program until after tracing the code by hand.

You can see the trace for the first few entries in the grid above. As you trace the program, cross out the `col` entries as you update them, as shown. However, make each row change start on a new row so that the graph on the right lines up with the row entries.

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ``` ```for (int row = 1; row <= 5; row++) { for (int col = 1; col <= row; col++) { if (col == 1 || row == col || row == 5) { cout << "*"; } else { cout << "."; } } cout << endl; } ```
3. Hand your paper to the instructor, who will verify you have the correct shape.

Do not show your paper to any other student and do not run the code until all students have completed the hand tracing.

As time permits, review the summary below and be prepared to answer the Check Yourself questions.

### 5.2.4: Summary

• Some looping applications have loops nested within other loops
• The structure of nest loops looks like:
```for (int outer = 1; outer < 4; outer++)
{
for (int inner = 1; inner < 4; inner++)
{
cout << outer << " " << inner << endl;
}
}
```
• We looked at one application that printed a simple table
• In addition, we looked at other applications that drew shapes, like squares and triangles, using stars ("*")

#### Check Yourself

1. How do you code a loop to display horizontal bar graphs? (5.2.1)
2. True or false? You can nest `if` statements but not loop statements. (5.2.2)
3. What is a nested loop? (5.2.2)
4. True or false? Hand tracing a loop means to list the values of the loop variables during each iteration. (5.2.2)
5. What do the following nested loops display? (5.2.2)
```for (int outer = 1; outer < 4; outer++)
{
for (int inner = 1; inner < 4; inner++)
{
cout << outer + inner << endl;
}
cout << endl;
}
```
6. True or false? The inner loop should be indented from the outer loop to make the structure clear. (5.2.3)

 Learner OutcomesAt the end of the lesson the student will be able to:Use sentinel values to terminate a loopDescribe the advantages of using a Boolean variable to control a loopUse `do-while` statements to repeat sections of codeDevelop strategies for processing input and handling errors

### 5.3.1: Indefinite Loops

• Recall our looping application that simulated the play of an exciting game
 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 ``` ```#include using namespace std; int main() { char repeat = 'y'; while ('y' == repeat) { cout << "\nPlaying an exciting game!\n"; cout << "Do you want to play again? (y/n) "; cin >> repeat; } cout << "\nThanks for playing!\n"; return 0; } ```
• Loops of this type are called indefinite loops because we do not know in advance how many time the loop will execute
• Instead, the loop executes until some condition is satisfied
• This behavior is different from a counting loop where we know how many times the loop will execute before the loop starts
• Most problems solved with indefinite loops make use of `while` statements

#### Check Yourself

1. True or false: with an indefinite loop, you often know in advance how many times the loop will repeat.
2. True or false: the best looping statement for an indefinite loop is a `for` statement.
3. True or false: a counting loop is a good example of an indefinite loop.

### 5.3.2: Indefinite Loop Example

• As an example of an indefinite loop, let us look at the problem of compounding interest
• If we invest \$10,000 at 5% interest, compounded annually, our savings grow like this:
YearBalance
0\$10,000
1\$10,500
2\$11,025
3\$11,576.25
4\$12,155.06
5\$12,762.82
• How many years does it take for the initial investment to double?
• To solve this problem we can use a `while` loop:
```double balance = 10000;
int year = 0;
while (balance < 20000) {
year++;
double interest = balance * 0.05; // 5% interest
balance = balance + interest;
}
```
• We can make the loop work for any interest rate, starting balance and target amount as shown below

#### Program with an Indefinite Loop

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ``` ```#include #include using namespace std; int main() { double balance = 0; double target = 0; double rate = 0; cout << "Enter the starting balance: "; cin >> balance; cout << "Enter the interest rate as a percent: "; cin >> rate; cout << "Enter the target amount: "; cin >> target; cout << fixed << setprecision(2); cout << "\nYear\tBalance\n"; int year = 0; cout << year << '\t' << balance << endl; while (balance < target) { year++; double interest = balance * rate / 100; balance = balance + interest; cout << year << '\t' << balance << endl; } cout << "\nTarget amount of \$" << target << " reached after " << year << " years.\n" ; return 0; } ```

#### Try It: Indefinite Loops (3m)

Run the above program and find the answers the following questions.

1. The above program includes the `<iomanip>` library because of ________.
2. If the interest rate is 5%, the number of years before an investment doubles is ________.
3. The number of years for an investment of \$10,000 to triple at 5% interest is ________.
4. If the interest rate is 1%, the number of years for an investment of \$10,000 to double is ________.
5. Can you easily predict how times the loop in the above program would repeat to double an investments at a certain interest rate? If so, how?

### 5.3.3: Processing a Sequence of Inputs

• Another common use for indefinite loops is to process a sequence of inputs
• As an example, let us add up (sum) a series of numbers
• Every number is added to the sum
• We use a loop to repeat the input until the user decides to stop
• Since we do not know how many number the user will enter, we use an indefinite loop as shown below
 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ``` ```#include using namespace std; int main() { double input = 1; double sum = 0; char repeat = 'y'; cout << "I will add up numbers for you\n\n"; while ('y' == repeat) { cout << "So far, sum = " << sum << endl; cout << "Enter a number: "; cin >> input; sum = sum + input; cout << "Another number? (y/n) "; cin >> repeat; } cout << "Ending sum: " << sum << endl; return 0; } ```

#### Terminating the Input with a Sentinel

• Whenever we read a sequence of input values, we need to have some way of terminating the input loop
• We could use a separate variable and input statement as we have done before:
```char repeat = 'y';
while ('y' == repeat) {
// ... statements to repeat
cin >> repeat;
}
```
• However, when entering numbers (or other data) repeatedly, answering an extra question each time through the loop becomes annoying
• One way to avoid asking an extra question is to use a sentinel value
• sentinel is guard who watches for something to happen
• Similarly, a sentinel in a program watches for a specific sentinel value that signals termination of a loop
• To use a sentinel value, we must have a special value in the input
• Some commonly used sentinel values for numeric input are 0 or -1
• However, if our application suggests another value, then we should use that value
• In psuedo-code, a sentinel loop generally looks like this:
```read the first value
while value is not the sentinel
process the value
```
• The following program is an update of the previous program to use a sentinel value to end the loop

#### Example Application Using a Sentinel Value for the Loop Test

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ``` ```#include using namespace std; int main() { double input = 1; double sum = 0; cout << "I will add up numbers for you\n\n"; cout << "Enter a number or 0 to exit: "; cin >> input; while (input != 0) { sum = sum + input; cout << "So far, sum = " << sum << endl; cout << "Enter a number or 0 to exit: "; cin >> input; } cout << "Ending sum: " << sum << endl; return 0; } ```

#### Check Yourself

1. A special value a program looks for in the input stream to know when to end user input is called a(n) ________ value.
2. In the example application, if a user enters a 0 as their first input the loop ________.
3. True or false: it is always possible to have a sentinel value. If you think it is not possible, give an example.

### 5.3.4: Maximum and Minimum Values

• Sometimes we need to find the maximum or minimum number of a group
• For instance we may want to know the highest score on a test
• We use a loop to ask the user for a new value repeatedly
• As we get each new score, we test to see if it is larger than the previous maximum
```if (score > max) {
max = score;
}
```
• We further explore the algorithm in the following activity

source

#### Activity: Maximum and Minimum Values

1. Students line up and each student chooses a number between one and 100.
2. Start at one end of the line and each student passes the maximum-value-so-far to the next student in line.
3. Repeat for the minimum value.

#### Developing an Algorithm for Maximum Value

1. Write down the algorithm for finding the maximum value in pseudocode. (3m)
2. Students review their algorithm with another student. (1m)

#### Activity Check

1. The initial minimum or maximum value in a series is the ________ value.
2. To compare if the next value is smaller or larger than the current value, we use an ________ statement.
3. Unless we know the number of values in advance, we collect the input with a(n) ________ loop.
1. for
2. while
3. counting
4. indefinite

#### Example of Finding a Maximum Value

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ``` ```#include using namespace std; int main() { double max = 0, value = 0; cout << "Enter positive numbers (0 or less to exit): "; cin >> value; max = value; while (value > 0) { if (value > max) { max = value; } cout << "Highest value so far: " << max << endl; cout << "Enter the next positive value (0 or less to exit): "; cin >> value; } if (max > 0) { cout << "Highest value: " << max << endl; } else { cout << "No data!\n"; } return 0; } ```

### 5.3.5: Input Validation

• Another common use for indefinite loops is input validation
• Input validation combines a loop with one or more `if` statements
• The input statement is placed inside the loop
• The `if`-statement tests for an incorrect input value
• The loop repeats while the user's input contains an error
• Since we do not know how many times the loop must execute ahead of time, the loop is indefinite
• For example, the following program uses a loop to ensure a user enters a positive number
• The `if` statement is used to decide when to output an error message

#### Example of Input Validation Using a Loop

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ``` ```#include using namespace std; int main() { double input = 0.0; // initialize value while (input <= 0) { cout << "Enter a positive number: "; cin >> input; if (input <= 0.0) { cout << "You must enter a positive number\n"; } } cout << "You entered: " << input << endl; return 0; } ```

#### Check Yourself

1. True or false: in the above code, the variable `input` must be initialized to a number less that or equal to zero to enter the loop.
2. True or false: input validation, like the above code, contains an indefinite loop.
3. True or false: many input validation loops, like the above, have two tests for the error condition.
4. The purpose of an `if`-statement when validating input is to ________.
1. initialize the input variable
2. display a message on error
3. loop when an error is found
4. print the value entered
5. The purpose of an `while`-statement in the above example is to ________.
1. initialize the input variable
2. check for errors
3. loop when an error is found
4. print the value entered

### 5.3.6: `do-while` Statements

• Sometimes we want to execute the body of a loop at least once and perform the loop test after the body was executed
• For this we can use the `do-while` (or just `do`) loop:
```do {
statements
} while (test); // loop test
```
• Where:
• statements: the statements to execute the first time and repeatedly while the test remains true
• test: the test condition to evaluate
• The loop test is placed after the body and executes at the end of the loop
• The statements in the body of the loop always execute at least once
• One common use of a `do-while` loop is to validate user input
• The following code shows an example where we force the user to enter a positive value

#### Example `do-while` Loop Used to Validate Input

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ``` ```#include using namespace std; int main() { double input = 0.0; // initialize value do { cout << "Enter a positive number: "; cin >> input; if (input <= 0.0) { cout << "You must enter a positive number\n"; } } while (input <= 0.0); // test condition at end cout << "You entered: " << input << endl; return 0; } ```

#### When to Use `do-while` Statements

• Use the `do-while` loop to force a minimum of one iteration
• Note that we can accomplish the same control flow with a `while` loop
• However, in some cases we can save a statement by using a `do-while` loop

#### Check Yourself

1. True or false: in the above code, the variable `input` must be initialized to a number less that or equal to zero to enter the loop.
2. True or false: the test of a `do-while` loop occurs at the end of the loop.
3. True or false: the body of a `do-while` loop always executes at least one time.
4. The reason to use a do-while loop, instead of a `while` loop, is to ________.
5. After reading this comic, explain the potential problem with do-while.

### 5.3.7: Checking for `cin` Failure

• Another problem arises if the user enters a string when we expect a number
• For instance, in the following, we get incorrect results if the user enters "seven"
```double input = 0.0;
cin >> input;
```
• The problem is that `cin` cannot convert the word "seven" into the number 7
• When this happens `cin` fails, sets an error flag and skips the rest of the input operation
• We can detect the failure condition using code like:
```if (cin.fail()) {
cout << "The stream failed\n";
}
```
• The opposite of `cin.fail()` is `cin.good()`
```if (cin.good) {
cout << "The stream is good\n";
}
```
• Another way to test for `cin` failure is:
```cin >> input;
if (cin) {
cout << "The stream is good\n";
} else {
cout << "The stream failed\n";
}
```
• Using `cin` by itself is the same as using `cin.good()`
• Yet another commonly used strategy is:
```if (cin >> input) {
cout << "The stream is good\n";
} else {
cout << "The stream failed\n";
}
```
• If `cin >> input` fails to read a correct type of data then `cin` fails and returns `false`
• To clear the failed state we must clear both the error state and the input stream like:
```cin.clear(); // clear error state
cin.ignore(1000, '\n'); // clear input buffer
```
• Using `cin.clear()` will clear the error state but leaves the bad input in the input stream
• Adding `cin.ignore(1000, '\n');` will clear all the input a user enters until the user presses an enter key
• The `1000` is just a large number

#### Example Program with Input Validation

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ``` ```#include using namespace std; int main() { double input = 0.0; do { cout << "Enter a positive number: "; cin >> input; if (cin.fail()) { cout << "You must enter digits, not words\n"; cin.clear(); cin.ignore(1000, '\n'); input = -1; // set loop test to fail } else if (input <= 0.0) { cout << "You must enter a positive number\n"; } } while (input <= 0.0); cout << "You entered: " << input << endl; return 0; } ```

#### Failure as a Sentinel Value

• We can detect `cin` failure with a `while`-loop like we can with `if`-statements
```while (cin.fail())
```
• If `cin` fails from the wrong type of input, we can treat if as a sentinel value for a loop
• For example, if we have a series of numbers to enter we can exit the loop by entering a letter
```int sum = 0;
int input = 0;
cout << "Enter a number or q to quit: ";
while (cin >> input) {
// the stream did not fail
sum += input;
cout << "Enter a number or q to quit: ";
}
// cin has failed
cout << "Sum: " << sum << endl;
```
• If we use `cin` again, we will need to clear the input stream and error state as before
```cin.clear(); // clear error state
cin.ignore(1000, '\n'); // clear input buffer
```

#### Check Yourself

1. True or false: when a user enters the wrong type of data, `cin` may fail.
2. To check `cin` for failure, call the `cin` function named ________.
3. To clear a `cin` failure call the ________ function.
4. Of the following, ________ will clear the input buffer.
1. `cin.clear();`
2. `cin.clearBuffer();`
3. `cin.ignore(1000, '\n')`;
4. `cin.ignore(1000 or '\n');`

### 5.3.8: Using Boolean Variables

• Another way to control loop termination is to use a Boolean variable
• The advantage of using boolean variable is that we can check multiple conditions even without a sentinel value
• The following is the same validation loop rewritten using a Boolean variable

#### Example Application Using a Boolean Variable for the Loop Test

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ``` ```#include #include using namespace std; int main() { double input = 0.0; bool more = true; do { cout << "Enter a positive number: "; cin >> input; if (cin.fail()) { cout << "You must enter digits, not words\n"; cin.clear(); cin.ignore(1000, '\n'); } else if (input < 0.0) { cout << "You must enter a positive number\n"; } else { more = false; } } while (more); // test condition cout << "You entered: " << input << endl; return 0; } ```

#### Simplified Boolean Test Conditions (Optional)

• Recall that test conditions in loops and if statements evaluate to either `true` or `false`
• For this reason, most professional programmers consider the following test conditions amateurish:
```while (more == true)  // avoid
while (more != false) // avoid
```
• The reason is that `== true` and `!= false` are not needed for correct operation
• Instead, we can simplify either test condition to:
```while (more)
```
• However, if using a relational operator is clearer then do so

#### Check Yourself

1. True or false: you can use a Boolean variable to control loop termination.
2. True or false: the following two loop conditions are equivalent for the Boolean variable named `more`.
```while (more)
while (more == true)
```

### Exercise 5.3: Processing User Input (10m)

In this exercise we use indefinite loops to process user input and to ensure correct user input.

#### Specifications

1. Copy the following program into a text editor, save it as `scores.cpp`, and then compile and run the starter program to make sure you copied it correctly.
```#include <iostream>
#include <climits>   //needed to use the INT_MAX constant
using namespace std;

int main() {

return 0;
}
```
2. Declare two variables of type `double` named `sumScores` and `nextScore` and initialize the variables to `0`. In addition, declare an integer variable named `count` and initialize it to `0`

Compile your code to make sure you declared the variables correctly.

3. Now we want to use a loop to enter a series of scores. Since we do not know how many scores to enter, we use an indefinite loop like the following:

In addition, add a statement to display `sumScores` after the loop.

Compile your code to make sure you added the loop correctly. To exit the loop you will need to enter a negative number.

4. The loop includes statements to collect the sum of the scores in the variable named `sumScores`. Add a statement after the loop to print `sumScores` to the console. When you run the program after adding this code, the output should look like:
```Score 1: 38
Score 2: 39
Score 3: -1

Sum of scores: 77
```

The loop uses the `sumScores` variable to accumulate scores during each repetition of the loop like that shown in lesson: 5.3.3: Processing a Sequence of Inputs.

5. We could write our indefinite loop using a `do`-`while` loop instead. Comment out your existing loop and  put this do-while loop below it in your file:

Note that the statements inside the loop did not change, only the loop statement itself. To make sure you made the changes correctly, compile and run your code and check to see if it works the same. The difference between a `while` and `do-while` loop is that a `do-while` ensures the body of the loop is executed at least once. For more information see lesson: 5.3.6: do-while Statements.

6. One problem with our program is the user can still enter letters instead of digits. We can prevent this error by checking `cin.fail()` and looping until the user enters a correct value. Replace the current `if` statement with the following:

Note that the second `if` statement is the same as the current `if` statement. Compile and run your program to make sure you added the changes correctly.

7. Try entering letters instead of digits and verify you see an error message. For more information see section: 5.3.7: Checking for cin Failure.

8. Save scores.cpp and submit it to Canvas Ex 5.3.

### 5.3.9: Summary

• In this section we looked at using indefinite loops
• With an indefinite loop, we do not know how many time the loop will execute ahead of time
• One example was the main loop, where we let the user repeat a program
• Since we do not know how many times the user will repeat ahead of time, the loop is indefinite
• Another indefinite loop example was how long it took an investment to double
• The amount of time depends on the investment and the interest rate
• Another common use for indefinite loops is to process a sequence of inputs
• Whenever we read a sequence of input values, we need to have some way of terminating the input loop
• Since entering extra data each time through a loop is annoying, we discussed using a sentinel value to terminate the loop
• A sentinel controlled loop looks for a sentinel value in the input data
• A sentinel value is a special number (or other data) used to signal termination of a loop
• We looked at how to sum numbers with a sentinel-controlled loop
• Another common use for indefinite loops is input validation
• Input validation combines a loop with one or more `if` statements
• The loop repeats input until the user enters reasonable input
• Since we do not know how many times the loop must execute ahead of time, the loop is indefinite
• Another looping statement is the do-while loop, which tests the condition at the end of the loop body:
```do {
statements
} while (test); //loop condition
```
• Testing at the end ensures a minimum of at least one iteration
• We also looked at how to test `cin` for failure
• The cin input stream fails if the user enters a string when we expect a number
• We looked at how to add checks for `cin` failure to our input validation
• Finally, we discussed a step-by-step procedure for developing loops

#### Check Yourself

1. What is an indefinite loop? (5.3.1)
2. How many times does an indefinite loop execute? (5.3.1)
3. For the program in section 5.3.2, how many years does it take to double \$10,000 at 10% interest? (5.3.2)
4. What is a sentinel value? (5.3.3)
5. What is the advantage of using a sentinel value to terminate a loop? (5.3.3)
6. What statements do we need to find a minimum or maximum value in a series of input? (5.3.4)
7. What is input validation? (5.3.5)
8. What is the difference between a `while` and a `do-while` loop? (5.3.6)
9. What is a test condition you can use to see if `cin` has failed? (5.3.7)
10. What is a good test to validate that the user did not enter a string after the following statements execute: (5.3.7)
```double x;
cout << "Enter a number: ";
cin >> x;
```
11. What two statements can you use to fix `cin` if it has failed due to bad input? (5.3.7)
12. What is the advantage of using a Boolean variable to control an indefinite loop? (5.3.8)