Welcome to Lesson 11!

Learning Objectives
By the end of today's class, you should know...
  • What is a loop?
  • What is a while loop?
  • What is the syntax of a while loop?
  • How does the syntax of a while loop compare to an if statement?
  • What are 4 common uses of while loops?
    • Give an example of each one.
  • What is an infinite loop?
  • What are some other common mistakes people make when writing loops?

Announcements

  • Quiz 4 on Wednesday
    • if - else if - else (multiway branches)
    • logical operators
    • numbers, operators and precision
    • while loops <--today
  • Return midterms in the last 5 minutes of class. 
  • Excellent midterm results!
    • As: 31
    • Bs: 7
    • Cs: 3
    • Ds: 1
    • Fs: 3

Pre-Assessment Activity

Review of Conditionals:
  • Imagine that a local radio station is holding a contest to give away a year's supply of free pet food to one lucky winner.
  • To win the contest, you must meet the following criteria:
    • You must be caller 19
    • The pet your own must be one of the following: dog, cat, rabbit
    • You must be between the ages of 18 and 65.
  • Which of the following test conditions will correctly determine the winner of the contest
a. if (numCaller = 19 && (pet = "rabbit" || pet = "cat" || pet = "dog") && age >= 18 && age <= 65)
cout << "You are the winner!";

b. if (numCaller == 19 && (pet == "rabbit" || "cat" || "dog") && age >= 18 && <= 65)
      cout << "You are the winner!";

c. 
if (numCaller == 19 || (pet == "rabbit" && pet == "cat" && pet == "dog") || age >= 18 && age <= 65)
      cout << "You are the winner!";


d. 
if (numCaller == 19 && (pet == "rabbit" || pet == "cat" || pet == "dog") && age >= 18 && age <= 65)
      cout << "You are the winner!";

e. 
if (numCaller == 19 && (pet == "rabbit" || pet == "cat" || pet == "dog" && age >= 18) || age <= 65)
cout << "You are the winner!";

Introducing Loops

  • In your daily life, there are many actions that you repeat until some condition is met.
  • For example: 
    • You might run on the treadmill at the gym until 30 minutes are up.
    • You might wash dishes until the pile of dirty dishes is gone.
    • You might take classes every quarter until you receive your degree.
    • Can you think of any others?
  • When we write code, often times we find ourselves repeating statements.
  • Loops allow us to carry out repetitive steps in our code without having to re-write the same statements over and over.
  • These loops will run until some test condition is met, just like the examples above.
  • You wrote your first loops when you did your Hour of Code lab assignment.
    • When did you need loops in this assignment?

Simple Loops

  • loop is a block of code that can execute repeatedly
  • Whether or not a program repeats a block of code is determined by a test condition
  • The test condition is checked each time the loop executes
  • In general, loops have three components:
    • Initialization code
    • Test condition -- evaluated during the loop
    • Loop body with some way to change the test condition
  • There are three loop statements in C++:
    • for
    • while
    • do...while
  • We will start with the simplest of the three -- the while statement

While Loops

  • The simplest looping structure is the while statement
  • A while statement has a test condition and a body, like an if statement
  • Before each execution of the loop body, the while statement checks the test condition
  • If the test condition evaluates to true, then our program executes the body of the loop
  • When the program reaches the end of the loop body, it automatically returns to the while statement
  • Here is the syntax of a while loop:
initialization statement;

while (test)
{   

    statements to repeat

}
  • For example:
string repeat = "y";
while ("y" == repeat) {
cout << "Do you want to play again? (y/n): "
cin >> repeat;
}
  • What does the while loop syntax remind you of?
  • The following flow chart shows how the while loop operates

Diagram of while Loop Operation

C++ while loop
Image source.

  • Let's look at an example.

Understanding the while Loop

  • The following looping application simulates the play of an exciting game
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main() {
    string 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;
}
  • Notice the structure of the code for the looping application
  • First was the statement to correctly initialize the looping condition:
    string repeat = "y";
  • Then came the while statement with the test condition
    while ("y" == repeat)
  • The loop executes the body of the loop if and only if the condition evaluates to true
  • Another important part of the loop is the statement: 
cin >> repeat;
  • Most loops have these parts:
    • Initialization code
    • Loop test condition
    • Loop body with some way to change the test condition
  • Question: What would happen if I replaced the while loop with an if statement?
  • We will explore the while loop more in the next exercise.

Group Activity: Candy Crush Loop

  • As a class, we are going to act out the following while loops
While Loop 1:
int num_pieces_candy = 12;
instructor.fill_with_candy(Bag, num_pieces_candy);
instructor.hand_bag(first_student);
while (num_pieces_candy > 0)
{
    student.takeOnePieceCandy();
    student.passBag(next_student);
    num_pieces_candy--;

}
  • With your partner, discuss for the while loop above: 
    • What is/are the initialization statement(s)?
    • What is the loop test condition?
    • What are the statements that repeat?
    • Which statement will ultimately cause the test condition to fail?
  • Now, let's act out While Loop 1!
While Loop 2
instructor.fill_with_candy(Bag);
instructor.hand_bag(first_student);
while (Bag != empty)
{
    student.takeOnePieceCandy();
    student.passBag(next_student);
}
  • With your partner, discuss for the while loop above: 
    • How is the above while loop different from while loop 1
    • How many times will the statements inside while loop 2 execute?
    • Were you able to state an exact number for while loop 2? What about loop 1?
    • How many conditions are controlling the loop?
  • Now, let's act out While Loop 2!

Activity 11.1: Counting Down...
  • Grab a partner for pair programming.
  • Open up CodeBlocks and create a new C++ file named countdown.cpp.
  • Imagine we are at NASA Mission Control.
  • A new space ship is about to be launched.
  • Let's write a program that counts down until take off. See the sample output below:
NASA Mission Control readying for liftoff.
Initializing countdown from 10...
10
9
8
7
6
5
4
3
2
1
We have liftoff!
  • We are going to write this program in two ways.


Part 1: Repetition, Repetition, Repetition (10 pts)
  • The first program should use 13 cout statements to achieve the above output.
  • Let's get to work!
  • Add your name and section in appropriate block comments, include the iostream library and use the standard namespace.
  • Don't forget a main() function.
  • Now, create a new C++ file called liftoff.cpp.
  • Declare an integer variable called countdown at the top of main and set it equal to 10.
  • Now, write a cout statement to output the following:
NASA Mission Control readying for liftoff.
  • Add another cout statement to print the following to the console:
Initializing countdown from 10...
  • Next, in a pair of statements, lets print the contents of countdown and then decrease its value by 1.
  • Add the following two statements to your code:
cout << countdown << endl;
countdown--;
  • You will need to repeat these two lines of code 10 times in your program.
  • Copy the two lines and then paste them into your program 9 more times.
  • You should have a very repetitive program by now!
  • Finally, add a cout statement to print out "We have liftoff!" below the numbers.
  • Run your code to make sure that your output is identical to my output above.
  • When you are finished and the program is working properly, upload it to Catalyst.

Part 2: Using a While Loop (10 pts)
  • Let's alter the above program to be written more efficiently with a loop.
  • First, take a look at your code.
  • Which part of the code is repetitive?
  • Hint: The repetitive lines will go inside the while loop.
  • We need a while loop to count down from the number entered by the user. Create a while loop that looks like this:
while (test will go here) {
    //statements
}
  • What should go inside the test?
countdown > 0
  • Why do you use > 0 here?
  • Inside the curly braces of the while loop, we need to print out the contents of the countdown variable and then decrease its value by 1.
  • Take one of your pairs of cout statement and variable decrement and place it in the curly braces of the while loop.
  • Now, you can erase the other 9 pairs of statements.
  • Finally, below your while loop, there should now be only one cout statement
  • Run your program to make sure it is working the same as before.
  • When you are finished, upload this new version to Catalyst.

About those Curly Braces

  • Like the if-statement, the curly braces of a while loop are optional
  • Technically, the while statement affects only the single statement that follows
  • We use curly braces to make that one statement into a block of statements
  • This allows us to put any number of statements within the body
  • Curly braces are not always required, but the best practice is to always include them

Program Style: Indent Statements Inside a Loop

  • It is important to format the loop code correctly:
    string repeat = "y";
    while ("y" == repeat) {
        // ... statements to repeat
        cin >> repeat;
    }
Also Accepted Style:
        string repeat = "y";
    while ("y" == repeat)
    {
        // ... statements to repeat
        cin >> repeat;
    }
  • Note how the repeated code is indented inside the loop
  • This lets us see easily which code is repeated and which is not
  • Also note the placement of curly braces
  • Different groups have different practices for placing curly braces in a loop statement

Applications of Loops

  • Let's look at 4 common loop applications:

1. Indefinite Loops

Recall our looping application that simulated the play of an exciting game


#include <iostream>
using namespace std;

int main() {
    string 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 you do not know in advance how many time the loop will execute
  • This behavior is different from a counting loop where you know how many times the loop will execute before the loop starts
  • With an indefinite loop we can solve a new set of problems
  • Most problems solved with indefinite loops make use of while statements


2. 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

#include <iostream>
using namespace std;

int main() {
    double input = 1;
    double sum = 0;
    string 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;
}

3. 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:
    string 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
  • 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

#include <iostream>
using namespace std;

int main() {
    double input = 1;
    double sum = 0;

    cout << "I will add up numbers for you\n\n";
    while (input != 0) {
        cout << "So far, sum = " << sum << endl;
        cout << "Enter a number or 0 to exit: ";
        cin >> input;
        sum = sum + input;
    }
    cout << "Ending sum: " << sum << endl;

    return 0;
}


4. 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


#include <iostream>
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;
}
  • We will explore all of these applications in our programs as we continue to write loops.

Partner Review
Find a partner and answer the following question...
  • Which of the following four applications of loops best describes our Candy Crush While Loop 2?
    • Indefinite Loop?
    • Input Validation?
    • Processing a Sequence of Inputs?
    • Terminating the Input with a Sentinel?
  • Candy Crush Loop 1 is a counting loop, which we will discuss more next class.

Activity 11.2: Guessing Game Redux (10 pts)

  • Copy the following program into a text editor, save it as loopy.cpp, and then compile and run the starter program to make sure you copied it correctly.
    #include <iostream>
    using namespace std;
    
    
    int main() {
        int guess = 0;
        cout << "I'm thinking of a number between"
             << " 1 and 10.\nCan you guess it?\n\n"
             << "Enter your guess: ";
        cin >> guess;
    
        if (7 == guess)
        {
            cout << "*** Correct! ***\n";
        }
        else
        {
            cout << "Sorry, that is not correct.\n";
            cout << "Try again.\n";
        }
        return 0;
    }
    
  • Add the following code after the statement int guess = 0; and before the cout statement:
    string repeat = "y";
    

    This is the initialization code that we will use for the test condition that comes next.

  • We want to repeat all the rest of the code in our program. For this we need to add a while statement such as:
    while ("y" == repeat) {
        // Place the rest of the code after the initialization
        // and before the return 0 between these curly braces.
    }
    

    Statements inside the curly braces repeat while the test condition in the parenthesis, ("y" == repeat), evaluates to true. 

  • Inside the while loop we need some way to change the test condition. We change the test condition by letting the user enter a value for therepeat variable by adding the following code at the end of the loop just before the closing curly brace:
    cout << "\nDo you want to play again? (y/n) ";
    cin >> repeat;
    

    Without these two statements our loop would have no way to exit. A loop with no way to exit is known as an infinite loop

  • Formatting a loop is important. Indent all the code within the curly braces of the while loop. 
  • As a final part of our program, we add the infamous phrase: "Game Over". Add the following statement after the closing curly brace of the while loop:
    cout << "Game over\n";
    
  • Compile and run your program again and verify the output looks like:
    I'm thinking of a number between 1 and 10.
    Can you guess it?
    
    Enter your guess: 3
    Sorry, that is not correct.
    Try again.
    
    Do you want to play again? (y/n) y
    I'm thinking of a number between 1 and 10.
    Can you guess it?
    
    Enter your guess: 7
    *** Correct! ***
    
    Do you want to play again? (y/n) n
    Game over
    
  • Submit your program source code to Catalyst.
  • If you finish early, find someone to help! Remember, you learn by teaching others.

Completed Program

When finished, your application should look like the following. Note especially the extra indentation within the curly braces of the while loop.



Conditional Pitfalls

  • Unfortunately, you can write many things in C++ that should be incorrect but end up working for some obscure reason
  • This means that you can code something that should create an error message but does not
  • Thus, a program may compile and run with no error messages but still be wrong
  • Since you may not realize that it is wrong, it can be hard to find and correct these types of errors

Strings of Inequalities

  • One common mistake is to use = when you meant to use ==
  • For example, look at the test condition in the following code:
    if (guess = 7) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
    
  • Notice that the condition is really an assignment statement and not a test
  • You would think that it would fail to compile -- but it does not
  • However, it will not work as you might expect
  • A way to prevent this type of problem is to reverse the order of your test condition:
    if (7 = guess) {
  • Now the compiler will give you an error message and your code will not compile:
    guess.cpp: In function `int main()":
    guess.cpp:10: error: non-lvalue in assignment
    
  • However, if you correctly use == then your code will compile
    if (7 == guess) {

Strings of Inequalities

  • Do NOT use a string of inequalities like the following:
    int a = 5, b = 1, c = 10;
    if (a < b < c) {
        cout << "b is between a and c\n";
    } else {
        cout << "b is NOT between a and c\n";
    }
    
  • Your code may compile and run but give incorrect results
  • The test condition is evaluated by the computer from left to right
  • The first condition is a < b which evaluates to 0 (false)
  • The second condition is then 0 < c which evaluates to 1 (true)
  • Since the whole test condition evaluates to true you get an incorrect result
  • Instead, the correct way is to use && as follows:
    int a = 5, b = 1, c = 10;
    if (a < b && b < c) {
        cout << "b is between a and c\n";
    } else {
        cout << "b is NOT between a and c\n";
    }
    

Strings of Logical Operators

  • Logical expressions often read like "normal" English.
  • However, C++ requires more exactness than English
  • For example, the following code will compile and run but give wrong results:
    int guess;
    cout << "Enter a guess: ";
    cin >> guess;
    if (guess == 7 || 8) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
    
  • The test condition is evaluated by the computer from left to right
  • The left hand side is (guess == 7) which can evaluate to either true or false
  • The right hand side is 8, which is interpreted as true by C++
  • Since (something or true) is always true, then the test condition always evaluates to true
  • Instead, the correct way is to use || as follows:
  • int guess;
    cout << "Enter a guess: ";
    cin >> guess;
    if (guess == 7 || guess == 8) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }


Common Loop Pitfalls

  • Loops have many pitfalls for the unwary
  • The following are the most common problems you should look out for

Infinite Loops

  • Common error: unintentional infinite loop
  • For example, what is wrong with the following code?
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;

int main() {
    string repeat = "y";
    while ("y" == repeat) {
        cout << "\nPlaying an exciting game!\n";
        cout << "Do you want to play again? (y/n) ";
    }
    cout << "\nThanks for playing!\n";

    return 0;
}

Missing Curly Braces

  • Technically, the while loop executes a single statement after the parenthesis of the test condition
  • However, we usually use curly braces { } to expand the single statement
  • The curly braces let us put multiple statements in them
  • For example, what is wrong with the following code?
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;

int main() {
    string 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;
}

Empty Statements

  • Remember that statements are terminated by a semicolon
  • Is the following a legal statement?
    ;
  • This is known as an empty or null statement
  • Empty statements are a common source of infinite loops
  • For example, what is wrong with the following code?


#include <iostream>
using namespace std;

int main() {
    string 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;
}    

Wrap Up
  • With your partner, answer the questions from today's learning objectives

Upcoming Assignments