Welcome to Lesson 12!


Learning Objectives
By the end of today's class, you should know...
  • What are some common errors that are made when writing while loops?
  • What is a counting loop?
  • What are the three important components of a counting loop?
  • What is a for loop and why was it designed?
  • How does a for loop differ from a while loop?
  • What is an off-by-one error and how can you avoid this type of error?

Announcements

  • Quiz 5 on Monday
  • Return Quiz 4
  • Lab 6 due Friday

Review Activity

With a partner, answer the following questions:

  • Label the different parts of the following while loop as: update statement, initialization or test condition.

int count = 1;

while (count <= 10) {

    cout << count << endl;

    count++;

}

  • Correct the loops below. What will happen if you run the code BEFORE making the corrections?

Loop 1:

string repeat = "y";

while (repeat == "y") {

    cout << "Playing an exciting game!\n\n";

    cout << "Want to play again? (y/n): ";

        }

Loop 2:

    int counter = 1;

  while (counter <= 10) {

      cout << counter << endl;

  }


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;
}    

Counting Loops

  • Counting is a common task in our lives.
  • In programming, counting is also very common.
  • In programming we often use loops to count when we know exactly how many times we want a specific piece of code to repeat.
  • In fact, counting is such a common programming task, that a special type of loop was designed specifically for counting.
  • This loop is called a for loop, and we will be learning more about it in class today.

For Statements
  • As previously mentioned, counting is a very common use for 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.

small picture of someone climbing numbered steps of a stair

Image source.

  • A counter-controlled while loop has the form:
    int i = start;
    while (i < end) {
        ...
        i++;
    }
    
  • Where:
    • i: the name of a counter variable
    • start: the initial starting value
    • end: the final ending value

  • We can write this same counting loop as a for loop:
    for (int i = start; i < end; i++) {
        ...
    }
  • The for loop was especially designed for counting tasks.
    • Notice its compact syntax compared to the while loop.
    • All the conditions which define the loop are on a single line.

  • When writing a counting loop, we often have a choice of using either a for or a while loop, as both will accomplish the same task.
    • However the compact syntax of the for loop makes it preferable.
  • The following example shows the same loop written as both a while loop and a for loop:
//counting from 10 to 20 using a while loop
int i = 10; 
while (i <= 20)
{
    cout << i << endl;
    i++;
}

//counting from 10 to 20 using a for loop
for (int i = 10; i <= 20; i++)
{
    cout << i << endl;
}
  • What differences do you notice in the two loops above?
  • What are the starting values for the loops? Where are they located?
  • Test conditions?
  • Update statements?
  • Notice the use of the semi-colons in the for loop. Which statements end with semi-colon and which do not?

Another For Loop Example

#include <iostream>
using namespace std;

int main()
{
    int max = 0;
    cout << "This program uses a loop to count!\n";
    cout << "Enter the maximum number: ";
    cin >> max;

    for (int i = 1; i <= max; i++)
    {
        cout << i << endl;
    }
}

Anatomy of the For Loop

  1. When for loop is reached, execute the initialize statement (starting point).
    1. This initialization step occurs only once.
    2. Note that i is the most common choice for our counting variable.
    3. Ex above: int i = 1;
  2. Check if condition is true.
    1. This occurs right after initialization, and after every iteration. 
    2. Ex above: i <= max;
    3. if true then continue with Step 3
    4. Otherwise it is false  continue with Step 6
  3. Execute the block containing the statements to repeat (body)
  4. When the end of each iteration of the loop body is reached, execute the update statement.
    1. This occurs at the end of every completed iteration.
    2. Ex above: i++;
  5. Return to Step 2
  6. The loop is finished when the test condition becomes false
    1. Continue with statements after the loop


Diagram of for Loop Operation

C++ for loop

Image source.


Group Activity: Altering a For Loop
  • With your partner: Open up a new project in Eclipse called ForLoop, with a file named forLoop.cpp
  • Copy and paste the below for loop into your file.
  • Now, try altering the for loop to see if you can achieve the following results:
    • Can you make the loop print out the numbers from 0 up to and including the max?
    • Can you make it print out the numbers from 0, up to, but not including, the max?
    • Can you make it count up by 2s to the max?
    • Can you make the loop count down from the max to 0?
#include <iostream>
using namespace std;

int main()
{
    int max = 0;
    cout << "This program uses a loop to count!\n";
    cout << "Enter the maximum number: ";
    cin >> max;

    for (int i = 1; i <= max; i++)
    {
        cout << i << endl;
    }
}



Activity 12.1: Counting Down Part 3 (10 pts)
  • Find a partner for pair programming
  • Open up your countdown.cpp file from last class in Eclipse.
  • Locate the while loop in your code.
  • Alter this while loop to be a for loop.
  • Hint: Make sure that your for loop has 3 parts:
    • initialization (where do you want to start counting)
    • test condition (when should the loop fail?)
    • update statement (are you counting up or down here?)
  • Compile and run your program and verify that you still get the following output:
NASA Mission Control readying for liftoff.
Initializing countdown from 10...
10
9
8
7
6
5
4
3
2
1
We have liftoff!
  • Submit your program to Canvas when you are finished.


Applications of For Loops

  • We can use for loops in two ways:
  1. To repeat a task a specified number of times, where the task performed is not dependent on the counter.
    1. For example, making a bar graph (below).
  2. To repeat a task a specified number of times, where the task performed is dependent on the value of the counter.
    1. For example, summing a sequence of numbers (below).

Making Bar Graphs
  • We can use a counting loop to make a horizontal bar graph
  • Instead of displaying a number, we will display a series of "*" characters for the "bar"
  • Thus, all we need to change is the print statement:
    cout << i << endl;
    
    to become:
    cout << '*';
  • We can see this change in the following example:

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
18
#include <iostream>
using namespace std;

int main() {
    int number = 0;

    cout << "Enter a number and I will show its"
         << " bar graph.\nEnter your number: ";
    cin >> number;

    cout << "\nBar graph:\n";
    for (int i = 0; i < number; i++) {
        cout << '*';
    }
    cout << endl;

    return 0;
}

Summing Numbers

  • One common looping task is to input a list of numbers and calculate their sum
  • 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 can generalize our examples to sum from 0 to any number n.

Example Application to Sum a Sequence of Numbers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;

int main() {
    cout << "Enter the number to sum to: ";
    int number = 0;
    cin >> number;
    int sum = 0;
    for (int i = 1; i <= number; i++) {
        sum = sum + i; //using the counter as a value to add to my sum 
    }
    cout << "Total sum = " << sum << endl;

    return 0;
}

Activity 12.2: Tracing a Loop (10 pts)

In this exercise, we will trace the execution of the following for loop.

for (int i = 10; i <= 15; i++)
{
    if (i == 11 || i == 13 || i== 15)
        cout << "*";
    else
        cout << "!";
}

  • Find a partner. Then, open up Notepad (Not Eclipse) and create a new document called tracing.txt.
  • In the text editor write both your names at the top of the program.
  • Then, type what the output of the above for loop would be to the console.
  • Note, you should do this without running the code. 
  • Then, change the statement i <=15 to be i < 15.
  • Draw the output of the for loop with this alteration.
  • How is it different?
  • The instructor will be going over the examples so you can verify your answers and understanding.
  • Don't forget to upload your text document before the end of class.


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 you start at 0 or 1?
    • Are you counting up to a number (<), or up to and including a number (<=)?
  • To understand the counting loop you 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
  • For example, 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

Image source.

  • How many posts do you need for a fence with three sections?
  • 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
  • You can insert temporary output statements in your program to watch the variables, like:
    cout << "count=" << count << ", sum=" << sum << endl;

Activity 12.3: ASCII (10 pts)

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

Background

Recall that a char data type is stored by the computer as a number using the ASCII code (ASCII Table). Since a char is stored as an int by the computer, C++ lets you cast an int to a char.

int count = 65;
cout << (char) count << endl; //What does the (char) do?

This casting feature lets us construct our own ASCII table.

Specifications

  • Find a partner for pair programming.
  • Copy and paste the starter code into a file called ascii.cpp

int main() {
cout << "Displaying the characters from 32 to 127:\n\n";
for (int i = ????; i <=????; i++) {
cout << i << endl;
}
}
  • Alter the for-loop so that it counts from 32 to 127
  • Inside the for-loop, alter the cout statement as follows:
  • Compile and run your modified program and make sure your output looks like:
    (some output not shown)
    65      A
    66      B
    67      C
    (more output not shown)
    
  • When you are finished, play around with the starting and ending values of your for loop.
  • Can you find the ASCII value for any unusual characters, such as the 4 ranks of playing cards, smiley faces and musical notes.
  • It turns out that each of these symbols has its own ASCII value in C++!
  • Submit the final version of your file to Canvas when you are finished.


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

Upcoming Assignments
  • Assignment 12 due Monday at 9:20am on Canvas
  • Lab 6 due Friday at midnight