Welcome to Lesson 14!


Learning Objectives
By the end of today's class, you should know...
  • What is a nested loop?
  • What is an application of a nested loop?
  • What is a string index?
  • How do you "iterate" through the characters in a string using a for loop and string indexing?
  • How to use getline() to take in string input.
  • What is cin.ignore() and when is it needed?

Announcements

  • Quiz 5 after the break
  • Don't forget about Lab 7 for Friday


Review Questions

Find a partner and answer the following questions:
  • Change the following for loop into the equivalent while loop:

for (int i = 10; i < 20; i++)
{
    cout << "*";
}
  • What will the following for loop print to the console window?

for (int i = 0; i < 10; i++)
{

    if (i % 3 == 0)

        cout << "*";

    else

        cout << "!";

}


Nested Loops


About Nested Loops
  • Some applications require loops within loops, called "nested" loops
  • For example, you may use a nested loop to print a table of values
  • The following example shows a simple table created with nested loops
  • Let's follow the execution sequence before checking the result

Example of Nested Loops

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

int main()
{
    for (int outer = 1; outer < 4; outer++)
    {
        for (int inner = 1; inner < 4; inner++)
        {
            cout << outer << " " << inner << endl;
        }
    }
}

Tracing the Variables

  • To understand any looping application, you 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
  • You 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 variable outer changes only after the inner loop is finished
Memory Screen 
 outer  inner  
  1  11 1
   21 2
   31 3
   4 (end of loop)   
  2  12 1
   22 2
   32 3
   4 (end of loop)   
  3  13 1
   23 2
   33 3
   4 (end of loop)   
  4 (end of loop)     
  • 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


Nested Loop Example: Drawing Squares
  • Another example of a nested loop is to draw a square using stars ("*")
  • Remember our bar graph example with the for loop?

#include <iostream>
using namespace std;

int main() {
int size = 0;
cout << "Enter a number and I will show its"
<< " bar graph.\nEnter your number: ";

cin >> size;

cout << "\nBar graph:\n";

for (int row = 1; row <= size; row++) {
cout << '*';
}
cout << endl;

return 0;
}
  • Now, let's alter the program to contain a nested for loop.
  • We will place another for loop inside the first one.
  • The nested loop makes the bar graph print in 2D.
  • 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;
     }
  • 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 line of characters
    • 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 are indented yet again
  • Formatting note:
    • Whenever you type an opening brace ({) you should indent the next character
    • Whenever you type a closing brace (}) you 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
19
20
#include <iostream>
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;
    }

    return 0;
}
  • We can make the square hollow by using an if statement inside the inner loop to decide when to print characters
  • Develop test conditions that allow the characters to print only at the start and end of the columns and rows
  • Use an else clause to print spaces when not printing characters
  • Another example of a nested loop is to draw a triangle, which we explore in the next exercise

Activity 14.1: Tracing a Nested Loop!

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 last class.

Specifications

  • Find a partner.
  • Take out a piece of paper, put 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.
  • 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.
  • 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;
}
  • When you are finished tracing it on paper, draw your trace into the box provided on Canvas.
  • Do not show your paper to any other students and do not run the code until all students have completed the hand tracing.
  • The instructor will trace it on the board when everyone is finished.


Using Loops with Strings

Review: Strings Versus Characters

  • Remember that a string is a series of characters enclosed in double quotes such as:
    "Hello"  "b"  "3.14159"  "$3.95"  "My address is 378 Eastbrook Dr"
  • We can store text in a variable of type string, like:
    string firstName;             // declaration
    firstName = "Jennifer";       // assignment
    string lastName = "Parrish";  // declaration + assignment
    string fullName = firstName + " " + lastName; // concatenation (+) of 2 stings
    
  • On the other hand, a character is a single letter, number or special symbol
  • We enclose characters in a single quote, rather than a double quote, like:
    'a'   'b'   'Z'   '3'   'q'   '$'   '*'
  • Also, we can store a a single character using a variable of type char, such as:
    char letterA = 'A';
    char letterB = 'B';
    
  • Each character is stored as a number, using its ASCII Table value
  • By declaring a char variable or using single quotes, C++ knows to treat the number as a character
  • Thus, when we print a character, we see a letter rather than a number:
    char letter = 'A';
    cout << letter << 'B' << endl;
    
  • As we can see, a string is made up of characters and characters are numerical codes
  • We can use this information to work with characters and strings

Indexing a String

  • Strings have a built-in indexing system with each stored in a character sequence starting at 0 (zero)

  • We can access any individual character of a string variable using square brackets [ ]
  • The general syntax is:
    stringVariable[index];
  • Where:
    • stringVariable: the name of your string variable
    • index: the number of the character position
  • For example:
    string str = "abcdef";
    char firstLetter = str[0];
    cout << firstLetter << str[1] << endl;
    
  • The above code displays:
    ab
  • Notice that the square bracket notation returns a char data type
  • What will the following print?
#include <iostream>
using namespace std;

int main() {
      string sport = "Basketball";
      cout << "The league: " << sport[1] << sport[7] << endl;

      cout << "Abbreviation for this sport: " << sport[0] << sport[6] << endl;

     return 0;

}



Using a For Loop to Iterate Strings
  • Recall that member function length() returns the number of characters in a string variable:
    string s = "abcdef";
    int n = s.length();
  • After we know the length, it is easy to iterate through the individual characters of a string using a counting loop:
    cout << "Enter a message: ";
    string msg;
    cin >> msg;
    for (int i = 0; i < msg.length(); i++) {
        cout << "Char[" << i << "]: " << msg[i] << endl;
    }
    

Group Activity: Iterating Strings

  • Copy the following program into Eclipse, save it as test.cpp, and then compile and run the
    code

  • string msg = "Hello, world!";
    for (int i = 0; i < msg.length(); i++) {
        cout << i << ": " << msg[i] << endl;
    }
    
  • What do you see when you compile?




Wrap Up

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

Upcoming Assignments
  • Assignment 14 due Tuesday at 9:20am on Canvas
  • Lab 7 due Friday at midnight


~Have a Great 3-Day Weekend!~