4: Control Statements

What We Will Cover


Continuations

Homework Questions?

Questions from last class?

Which of the following statements is false?

  1. A literal string is enclosed in double quotes.
  2. The + operator is used to join, or concatenate, two strings to make one longer string.
  3. To include a double quote inside a string, you must put an escape character in front of it.
  4. Strings are stored in either 4 or 8 bytes, depending on the precision you want.

Partners

VTEA Surveys

4.1: Relationships, Logic and Truth

Objectives

At the end of the lesson the student will be able to:

  • Use relational expressions to produce boolean values
  • Use logical operators to code complex conditions

4.1.1: The Value of a Relationship

  • In addition to arithmetical operations, all computers can compare numbers
  • Many decisions can be reduced to choosing between two numbers
  • Comparing numbers can make computers seem "intelligent"
  • Expressions that compare operands are called relational expressions
    • Also called conditions
  • Simple relational expressions have one relational operator comparing two values
  • relational expression

  • A relational expression always evaluates to either true or false
  • The relational operators are:
  • Math Name C++ Example Result
    = Equal to == 5 == 10
    2 == 2
    false
    true
    Not equal to != 5 != 10
    2 != 2
    true
    false
    < Less than < 5 < 10
    5 < 5
    5 < 2
    true
    false
    false
    Less than or equal to <= 5 <= 10
    5 <= 5
    5 <= 2
    true
    true
    false
    > Greater than > 5 > 10
    5 > 5
    5 > 2
    false
    false
    true
    Greater than or equal to >= 5 >= 10
    5 >= 5
    5 >= 2
    false
    true
    true

  • You may use relational operators with integer, floating-point and character data

4.1.2: Comparing Characters

  • Character data can be evaluated using relational operators
  • For these comparisons, char values are automatically coerced to int values
  • Letters nearer to the start of the alphabet have lower numerical values
  • Thus a numerical comparison can decide the alphabetical order of characters
  • For example:
  • Expression Result
    'A' > 'C' false
    'D' <= 'Z' true
    'E' == 'F' false
    'G' >= 'M' false
    'B' != 'C' true

4.1.3: Logical Operators

  • Sometimes you want to consider several relational expressions at once
  • For this, we can use logical operators
  • Use ! operator to reverse value of expression
  • Use && to AND two or more conditions
  • Use || to OR two or more conditions
  • ! Operator
    If expr is... Then ! expr is... Example Result
    true false !true false
    false true !(5 < 2) true

  • && operator returns true only if expressions on both sides are true
  • && Operator
    If expr1 is... And expr2 is... Then expr1 && expr2 is... Example Result
    true true true 5 < 10 && 5 > 2 true
    true false false 5 < 10 && 5 < 2 false
    false true false 5 > 10 && 5 > 2 false
    false false false 5 > 10 && 5 < 2 false

  • || operator returns true if either expression is true
  • || Operator
    If expr1 is... || expr2 is... Then expr1 || expr2 is... Example Result
    true true true 5 < 10 || 5 > 2 true
    true false true 5 < 10 || 5 < 2 true
    false true true 5 > 10 || 5 > 2 true
    false false false 5 > 10 || 5 < 2 false

4.1.4: What is Truth?

  • "What is truth?" may seem more appropriate for philosophy than programming
  • However, in programming we have to know how the computer interprets truth
  • C++ stores true as 1 and false as 0
  • cout << true << endl;
    cout << false << endl;
    cout << boolalpha; // show output as true or false
    cout << true << endl;
    cout << false << endl;
    

4.1.5: Summary

  • Many decisions can be reduced to choosing between two numbers
  • Comparing numbers can make computers seem "intelligent"
  • Relational expressions include:
  • ==  !=  <   <=  >   >=
  • Similarly, you can compare letters since letters are stored as numbers
    • Used to alphabetize letters and words in a computer program
  • Relational expressions always evaluate to either true or false
  • When you need to compare several conditions, you use logical operators
  • !   &&  ||
  • For example:
  • 5 > 10 || 5 > 2

Exercise 4.1

With a partner, if needed, take 10 minutes to complete the following:

  1. Start a text file named exercise4.txt.
  2. Prepare the exercise header as described in the HowTo on submitting exercises
  3. Label this exercise: Exercise 4.1
  4. Submit all exercises for today's lesson in one file unless instructed otherwise

Specifications

For the values:

int a = 5, b = 2, c = 4, d = 6;

Record the value of each of the following relational expressions in your exercise4.txt file.

  1. a > b
  2. a != b
  3. d % b == c % b
  4. a * c != d * b
  5. b % c * a != a * b

As a final part of this exercise, run the following program and answer these questions:

  1. Given that the variables a and b have already been declared and assigned values, write an expression that evaluates to true if a is greater than or equal to zero and b is negative
  2. Given that the variables a and b have already been declared and assigned values, write an expression that evaluates to true if a is positive (including zero) or b is negative (excluding zero).
  3. Given the boolean variable isValid has already been declared and assigned a value of either true or false, write an assignment statement that reverses (toggles) the value.
#include <iostream>
using namespace std;

int main() {
    bool p, q;

    cout << "p\tq\t!p\tp && q\tp || q\n";
    cout << "-\t-\t--\t------\t------\n";

    p = true;
    q = true;
    cout << p << "\t" << q << "\t" << !p << "\t" ;
    cout << (p && q) << "\t" << (p || q) << endl;

    p = true;
    q = false;
    cout << p << "\t" << q << "\t" << !p << "\t" ;
    cout << (p && q) << "\t" << (p || q) << endl;

    p = false;
    q = true;
    cout << p << "\t" << q << "\t" << !p << "\t" ;
    cout << (p && q) << "\t" << (p || q) << endl;

    p = false;
    q = false;
    cout << p << "\t" << q << "\t" << !p << "\t" ;
    cout << (p && q) << "\t" << (p || q) << endl;

    return 0;
}

4.2: Selection Statements

Objectives

At the end of the lesson the student will be able to:

  • Choose appropriate selection statements
  • Code selection statements

4.2.1: Flow Of Control

  • Term flow 0f control refers to the order a program executes instructions
  • All programs can be written with three control flow elements:
  1. Sequence - continue with the next instruction
    • Sequence is the default operation
  2. Selection - a choice between at least two options
    1. Either execute some instruction based on a condition
    2. Or continue with the next instruction
    3. if
      if-else
      if else-if else-if ... else
      
  3. Repetition - a loop (repeat a block of code)
    At the end of the loop:
    • Either go back and repeat the block of code
    • Or continue with the next instruction after the block
    • while
      
  • We will start with selection statements

4.2.2: Using if Statements

  • Simplest selection statement is an if statement
  • Executes a section of code only if a condition is true
  • If the test condition is false, the computer skips the code
  • if (condition) {
       // execute statements only if true
    }
    
  • The test condition can be any expression that evaluates to true or false
  • For clarity, write the if on a different line than the statements
  • Also, indent the statements that are executed

For Example

  • What do you notice about the following code?
#include <iostream>
using namespace std;

int main() {
    int guess;
    cout << "I'm thinking of a number between"
         << " 1 and 10.\nCan you guess it?\n";
    cin >> guess;

    if (guess == 7) {
        cout << "*** Correct! ***" << endl;
    }
    return 0;
}

About those Curly Braces

  • Technically, the if statement affects only the single statement that follows
  • We use curly braces to make the following statement into a block
  • This allows us to put any number of statements within the block
  • Though curly braces are not always required, the best practice is to include them

4.2.3: Using if-else Statements

  • Sometimes we want to choose one action or another
  • If a condition is true
    • then do this
  • Otherwise it is false
    • so do something else
  • General syntax:
  • if (condition == true) {
        // execute statements only if true
    } else {
        // execute statements only if false
    }
    
  • For clarity, if and else are written on different lines than the statements
  • Also, the statements are indented

For Example

  • What do you notice about the following code?
#include <iostream>
using namespace std;

int main() {
    int guess;
    cout << "I'm thinking of a number between"
         << " 1 and 10.\nCan you guess it?\n";
    cin >> guess;

    if (guess == 7) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
    return 0;
}

Programming Style: Placement of Braces

  • Different practices for placing curly braces in a compound statement
  • In practice, you should use the style dictated by your company's policy
    • Or your professor's instructions
  • For the acceptable styles for this course see: Curly Braces

4.2.4: Nested if Statements

  • You can include if statements within other if statements
  • Each inner if statement is evaluated only if outer condition is met

For Example

  • What do you notice about the following code?
#include <iostream>
using namespace std;

int main() {
    double temp = 0;
    cout << "Enter a temperature: ";
    cin >> temp;

    if (temp > 65) {
        if (temp > 75) {
            cout << "That's too hot!\n";
        } else {
            cout << "That's just right.\n";
        }
    } else {
        cout << "That's cold!\n";
    }
    return 0;
}
  • Nested conditionals can be confusing if too deep
  • Rule of thumb: no more than three deep

"Dangling Else" Problem

  • Potential problem with nested if statements is the dangling else problem
  • if (condition1)
        if (condition2)
            Statement1;
    else
        Statement2;
    
  • Indentation is misleading and should be:
  • if (condition1)
        if (condition2)
            Statement1;
        else
            Statement2;
    
  • Common mistake is not matching else with the correct if
  • Rule: else always matches the last unmatched if
  • Avoid this problem by using curly braces to specify the grouping
  • if (condition1) {
        if (condition2) {
            Statement1;
        } else {
            Statement2;
        }
    }
    

4.2.5: Using if-else Chains

  • Often confusing when if statements are nested within other if statements
    • Should avoid this type of construction
  • However, a very useful construction is an if ... else if statement
  • Tests conditions sequentially until the first true condition is found
  • The first true condition executes the code within the block
    • Skips the remainder of the if-else chain
  • Often used to create a menu

For Example

  • What do you notice about the following code?
#include <iostream>
using namespace std;

int main() {
    double temp = 0;
    cout << "Enter a temperature: ";
    cin >> temp;

    if (temp > 75) {        // first condition
        cout << "That's too hot!\n";
    } else if (temp > 65) { // next condition
        cout << "That's just right.\n";
    } else {                // default condition
        cout << "That's cold!\n";
    }
    return 0;
}
  • Note the arrangement of if-else statements

Multiple Conditions

  • With logical operators (&&, ||, !), you can test for multiple conditions
  • For example, you can create condition that displays only if two conditions are true
  • What do you notice about the following code?
#include <iostream>
using namespace std;

int main() {
    double temp = 0;
    cout << "Enter a temperature: ";
    cin >> temp;

    if (temp >= 65 && temp <= 75) {
        cout << "That's just right.\n";
    } else {
        cout << "That's uncomfortable!\n";
    }
    return 0;
}
  • How could we get the same result using a logical OR operation?

4.2.6: Summary

  • Selection is a choice between at least two options
  • Selection statements include:
  • if
    if-else
    if else-if else-if ... else
    
  • Single statements are expanded into compound statements using blocks
  • Nested if statements are legal but often confusing
    • Which if does an else match up with?
    • Use curly braces to clarify
    • Better yet, avoid using nested if statements
  • In contrast, chains of if-else statements are very useful
    • Programs execute the code when the first condition matches
    • Often used to create menus

Exercise 4.2

  1. Label this exercise: Exercise 4.2
  2. Complete the following and record the answer any questions in your exercise4.txt file.

Specifications

A student's letter grade is calculated according to the following table:

Numerical Grade Letter Grade
greater than or equal to 90 A
less than 90 but greater than or equal to 80 B
less than 80 but greater than or equal to 70 C
less than 70 but greater than or equal to 60 D
less than 60 F

  1. Write a program that accepts a students numerical grade, converts the grade to an equivalent letter grade, and displays the letter grade.
  2. Q1: How do you make sure that only one condition is selected?

    Q2: How do you avoid the dangling-else problem?

  3. Submit your final program along with your exercise4.txt file.

You can use the following code to get started.

#include <iostream>
using namespace std;

int main() {
    double score;
    cout << "Enter a score: ";
    cin >> score;

    // Insert statements here

    return 0;
}

4.3: Repetition (Loops)

Objectives

At the end of the lesson the student will be able to:

  • Use while statements to repeat sections of code
  • Apply commonly-used looping patterns
  • Avoid common looping problems

4.3.1: Introduction to Loops

  • Loops are used to repeat sections of code
  • General loop structure:
    • Initialization code
    • Loop condition -- evaluated during the loop
    • Loop body
  • C++ has 3 loop statement
  • while
    do-while
    for
    
  • However, you can use any loop statement and achieve the same result
  • Thus, I am only going to teach the simplest loop statement at this time
  • Later on we will look at the other loop statements

4.3.2: Coding while Statements

  • Use a while loop to repeat a section of code
  • The repetition continues as long as the test condition remains true
  • while loop Syntax:
  • //Initialization
    ...
    while (condition) {  //loop condition
       //loop body
       ...
    }
    
  • Initialization statements usually precede the while loop
  • Checks the (condition) at start of every loop iteration
    • Continues as long as condition evaluates to true
  • Note that if the loop condition is false at first then the loop body never executes
  • The loop body can be a single statement or a block

4.3.3: Example Application: Play Again Program

  • The following application simulates the play of an exciting game
  • Note how the syntax matches the code
  • #include <iostream>
    using namespace std;
    
    int main() {
        char answer = 'y';
        while (answer == 'y') {
            cout << "\nPlaying an exciting game!\n";
            cout << "Do you want to play again? (y/n) ";
            cin >> answer;
        }
        cout << "\nThanks for playing!\n";
    
        return 0;
    }
    
  • Which statement initializes the loop variables?
  • Which part is the loop condition?
  • Which part is the loop body?
  • Loops of this type are often called the main programming loop

4.3.4: while-Loop Operation

While flow chart

Programming Style: Placement of Braces

  • Different practices for placing curly braces in a loop statement
  • For the acceptable styles for this course see: Curly Braces

4.3.5: Summary

  • Loops are used to repeat sections of code
  • General loop structure:
    • Initialization code
    • Loop condition -- evaluated during the loop
    • Loop body
  • The while loop is the most basic repetition statement
  • Many programs have a main program loop
  • Program repeats (iterates) until the user decides to exit

Exercise 4.3

  1. Label this exercise: Exercise 4.3
  2. Complete the following and record the answer any questions in your exercise4.txt file.

Specifications

  1. Update the guessing game program that follows to let the user make as many guesses as they choose.
  2. Submit your final program along with your exercise4.txt file.

I suggest that you use the following code to get started.

#include <iostream>
using namespace std;

int main() {
    int guess;
    cout << "I'm thinking of a number between"
         << " 1 and 10.\nCan you guess it?\n";
    cin >> guess;

    if (guess == 7) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
    return 0;
}

4.4: More Loops

Objectives

At the end of the lesson the student will be able to:

  • Apply commonly-used looping patterns
  • Avoid common looping problems

4.4.1: More About Loops

  • Loops provide more power to the programmer
  • Your programs can repeat sections of code
  • We will look at some common looping patterns
  • With the power of loops comes more problems
  • We will look at some of the common problems

4.4.2: Another Application: Accumulating Values

  • One common looping task is to calculates sums or products
  • For example, to sum the numbers from 0 through 4:
  • #include <iostream>
    using namespace std;
    
    int main() {
        //Loop initialization
        int counter = 1;
        int sum = 0;
        while (counter < 5) { //loop condition
            //loop body
            sum = sum + counter;
            cout << "After adding " << counter
                 << " sum = " << sum << endl;
            counter++; // adjust counter
        }
        cout << "Total sum = " << sum << endl;
    
        return 0;
    }
    
  • This is known as accumulating values
  • What would we change to compute the product of the numbers from 1 to 5?
  • What would we change to sum the even numbers from 1 through 10?
  • What would we change to sum the odd numbers from 1 through 10?

4.4.3: Looping Patterns

  • Let us look at some ways to use loops

Counter-Controlled Loops

  • Use loops this way when you know how many times to repeat a section of code
  • The key is a variable called the counter
    1. Initialize the counter variable to 0
    2. Set the loop condition to check for the maximum count
    3. Adjust the counter variable inside the body of the loop
  • For example:
#include <iostream>
using namespace std;

int main() {
    int count = 0; // initialize counter
    while (count < 5) { //loop condition
        //loop body
        cout << count << endl;
        count++; // adjust the counter
    }
    cout << "After loop count = " << count << endl;

    return 0;
}
  • A variation is to start at the maximum value and count down

Ask Before Repeating

  • Another pattern is to ask the user whether or not to repeat a loop
  • Often used to allow the user to control the flow of a program
  • For example:
#include <iostream>
using namespace std;

int main() {
    //Loop initialization
    double input = 0.0;
    double total = 0.0;
    char choice = 'Y';
    while (choice == 'Y' || choice == 'y') { //loop condition
        //loop body
        cout << "Enter a number: ";
        cin >> input;
        total = total + input;
        cout << "Enter another number? (Y/y to contine) ";
        cin >> choice;
    }
    cout << "Total: " << total << endl;

    return 0;
}
  • For a long list, this approach can be tiring
  • Often time, a better solution is to use a sentinel-controlled loop

Sentinel-Controlled Loops

  • Use a sentinel when you can use input data to tell the program when to stop
  • Looping continues as long as the data value read is not a sentinel value
  • When a sentinel value is read, the loop exits
  • For example:
#include <iostream>
using namespace std;

int main() {
    //Loop initialization
    double input = 0.0;
    double total = 0.0;
    while (input != -1) { //loop condition
        //loop body
        total = total + input;
        cout << "Enter a positive number or -1 to exit: ";
        cin >> input;
    }
    cout << "Total: " << total << endl;

    return 0;
}
  • input is the sentinel variable
  • The sentinel value is the number: -1
  • The program ends when the user enters the sentinel value

4.4.4: Common Loop Pitfalls

Infinite Loops

  • Common error: unintentional infinite loop
  • For example, what is wrong with the following code?
  • #include <iostream>
    using namespace std;
    
    int main() {
        int count = 0;
        while (count < 10) {
            cout << count << endl; // trace
        }
        return 0;
    }
    

Empty Statements

  • Remember that statements are terminated by a semicolon
  • Is the following a legal statement?
  • ;
  • 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() {
        int count = 0;
        while (count < 10); {
            cout << count << endl; // trace
            count++;
        }
        return 0;
    }
    

Off-By-One Errors

  • A common looping problem is the off-by-one error
  • Often a less-than is confused with a less-than-or-equal-to
  • For example, to sum the numbers between one and 10, what is wrong with:
  • #include <iostream>
    using namespace std;
    
    int main() {
        int sum = 0;
        int count = 1;
        while (count <= 10) {
            sum += count;
            count++;
        }
        cout << sum << endl;
    
        return 0;
    }
    

Tracing Variables

  • One good way to discover loop errors is to trace key variables
  • Tracing variables means watching them change as the program executes
  • You can insert temporary output statements in your program
  • For instance, we had trace statements in the infinite loop examples above
  • What variables would we trace for the off-by-one error example?

4.4.5: Nested Loops

  • Often necessary to have one loop inside another
  • Following example shows this structure
  • Let's follow the execution sequence before checking the result
#include <iostream>
using namespace std;

int main() {
    int outer = 1;
    while (outer < 4) {
        cout << "outer = " << outer << endl;
        int inner = 1;
        while (inner < 4) {
            cout << "  inner = " << inner << endl;
            inner++;
        }
        outer++;
    }
    return 0;
}
  • Which statements provide the trace to allow us to see the operation?

4.4.6: Summary

  • Several common uses of a loop
    • Counter-controlled loops
    • Ask Before Repeating
    • Sentinel-controlled loops
  • Several problems that can occur when using a loop
    • infinite loops: loops that "never" stop
    • Off-by-one errors: start or stop at a wrong value
  • Tracing variables is a good way to discover loop errors
  • It is legal code to have one loop nested inside another

Exercise 4.4

  1. Label this exercise: Exercise 4.3
  2. Complete the following and record the answer any questions in your exercise4.txt file.

Specifications

  1. Write a program that lists the ASCII characters numbered from 1 through 255.

Wrap Up

    Reminders

    Due Next: A3: Conversions (9/23/04)
    Exercise 3 and CodeLab Lesson 3 (9/23/04)
    A4: Tally Ho! (9/30/04)
    Exercise 4 and CodeLab Lesson 4 (9/30/04)

  • When class is over, please shut down your computer
  • You may complete unfinished exercises at the end of the class or at any time before the next class.
  • Instructions on submitting exercises are available from the HowTo's page.

Home | WebCT | Announcements | Day Schedule | Eve Schedule
Course info | Help | FAQ's | HowTo's | Links

Last Updated: September 29 2004 @14:36:36