4: Numbers, Conditions and Loops

What We Will Cover


Continuations

Homework Questions?

Questions from last class?

  • Who is thinking about pair programming?
  • Pair programming is worth extra credit
  • Success Strategies

Homework Discussion Questions

  1. How "natural" did it feel to use arithmetic in C++?
  2. How many if-statements did you need to solve the playing cards program?
  3. Did you run into any problems developing the Mad Libs program?
  4. Did anyone come up with a good Mad Libs for the extra credit?

Review Question

  • What is the value of x in: x = 'd' - 'a' + 'A';

4.1: More About Numbers

Learner Outcomes

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

  • Describe exponential (scientific) notation
  • Format numbers during output
  • Discuss the reasons to use named constants instead of numbers
  • Rewrite assignment statements into shortcut alternatives
  • Generate code to convert data from one type to another
  • Diagnose problems with arithmetic precision and range and formulate solutions

4.1.1: Numbers and Arithmetic

  • Recall that C++ uses the following operators for arithmetic:
    • + for addition
    • - for subtraction
    • * for multiplication
    • / for division
    • % for modulus (remainder)
  • The dash is also used for negation (minus sign)
  • We write arithmetic expressions using combinations of numbers, variables and operators
  • For example:
    double area = 0.0, radius = 4.3;
    area = 3.14159 * radius * radius;
    
  • Also recall that the results of integer division are truncated
    7 / 2       // 3
  • You must use modulus operator (%) to get the remainder value
    7 % 2       // 1 (remainder)
  • In addition, you use mathematical functions for more complex operations
    cout << sqrt(3.0 * 3) << endl;
  • C++ processes arithmetic expressions in the same order (precedence) as algebra:
    1. Parenthesis: ( )
    2. Function calls
    3. Unary operators: +, -
    4. Multiplication, division, modulus: *, /, %
    5. Addition, subtraction: +, -
  • Since parenthesis are processed first, you use parenthesis to change the order of operations
  • Now that we understand the basics of C++ arithmetic, we need to explore some additional features, limitations and quirks
  • We explore these items in the next exercise

4.1.2: Exponential Notation

  • Floating-point numbers can use exponential notation, which is similar to scientific notation
  • Exponential notations lets us express both very large and very small values in a compact form
  • For example:
Decimal Notation Scientific Notation Exponential Notation
1234 1.234 x 103 1.234e3
98765 9.8765 x 104 9.87654e4
0.0123 1.23 x 10-2 1.23e-2
0.000625 6.25 x 10-4 6.25e-4
  • The letter E stands for Exponent
  • The number following the E is the power of 10 to multiply the first number by
  • Thus, "E" means "times ten raised to the power"
  • An easy way to multiply by 10 is to move the decimal place for a number
  • A positive power of 10 moves the decimal point to the right
  • A negative power of 10 moves the decimal point to the left

How Large is 1.7E308?

  • The largest possible double is 17 followed by 307 zeros
  • How large is that?
  • The current estimate of the number of atoms in the universe is between 1.0e79 to 1.0e81
  • Mathematicians use the term "googol" for a very large number: 1.0e100
  • Data type double easily encompasses these numbers
  • What large number cannot be represented by type double?

4.1.3: Decimal Formatting

  • Sometimes programs may not display numbers as you would expect!
  • Consider the following program and what it will display:
    #include<iostream>
    using namespace std;
    
    int main() {
        double price = 78.50;
        cout << "The price is $" << price << endl;
    }
    
  • We must explicitly tell C++ how to output numbers in our programs!
  • These commands do not produce any output but change how cout outputs floating-point numbers
  • "Magic Formula" to force decimal places:
    cout << fixed             // fixed notation, not scientific
         << setprecision(2);  // show 2 decimal places
    
  • The commands fixed and setprecision are known as manipulators because you can manually change how cout works
  • You can put both commands on one line:
    cout << fixed << setprecision(2);
  • Also, you can combine the commands with other output:
    cout << "The price is $"
         << fixed << setprecision(2)
         << price << endl;
    
  • To use these commands, you must include the iomanip library:
    #include <iomanip>
    
  • Once we set the decimal formatting, it stays set
  • We will discuss manipulators in more detail later in the course

4.1.4: Constants and Magic Numbers

  • A constant variable (or constant) is a variable that cannot change after being assigned a value
  • Sounds oxymoronic, but is actually quite useful
  • To declare a constant, we use the keyword: const
    const int MY_CONST = 1;
  • Note that you must assign a value when the constant is declared
  • Also note that the name is all uppercase letters with an underscore separator
  • This is a common coding convention that you must follow

Magic Numbers

  • Imagine that you are a programmer hired to modify a payroll program
  • You come across the following section of code:
    double pay;
    pay = hours * 7.5 + (hours / 40)
          * (hours - 40) * 7.5 * 0.5;
    
  • The numbers are important to the program, but what do they mean?
  • Numbers like these are called "magic numbers"
  • They are magic because the value or presence is unexplainable without more knowledge
    • Often, no one knows what they mean after 3 months, including the author
  • A programmer can often infer the meaning of numbers after reading the code carefully
  • A much better coding style is to use named constants rather than literal numbers
  • For example:
    const double WAGE = 7.5;
    const double OVERTIME_ADDER = 0.5;
    const int HOURS_PER_WEEK = 40;
    double pay;
    pay = hours * WAGE + (hours / HOURS_PER_WEEK)
          * (hours - HOURS_PER_WEEK) * WAGE * OVERTIME_ADDER;
    
  • Now it is much easier to understand the code and see any problems or limitations in it
  • Another reason to use named constants is that it is easier to change the value of the number
  • In the above example, we can easily change the WAGE without making errors in other parts of our code

Programming Style: Constant Variables and Magic Numbers

  • Since the meaning of literal ("magic") numbers is hard to remember, you should declare constants instead:
    const int FEET_PER_YARD = 3;
    const double PI = 3.14159265358979323846;
    const double WAGE = 7.5;
    const double OVERTIME_ADDER = 0.5;
    const int HOURS_PER_WEEK = 40;
    
  • Note that the name is all uppercase letters with an underscore word-separator
  • This is a common coding convention that you must follow for your constants

More Information

Exercise 4.1

In this exercise we explore some additional numeric features of C++.

Specifications

  1. Copy the following program into a text editor and save it as price.cpp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int main() {
        string name;
        double price = 0;
    
        cout << "Enter the product name: ";
        cin >> name;
        cout << "Price of the " << name << ": ";
        cin >> price;
    
        // Insert new statements here
    
        cout << "Total price: $" << price << endl;
    
        return 0;
    }
    
  2. Compile and run the starter program to make sure you entered it correctly.

    When you run the program, the output should look like this:

    Enter the product name: iPod_Nano
    Price of the iPod_Nano: 178.50
    Total price: $178.5
    

    Note the format of the numbers output for the total price. We will address this formatting issue later in the exercise.

  3. Run the program again for a product with a very high cost, like a Boeing 777:
    Enter the product name: Boeing__777
    Price of the Boeing_777: 212345678
    Total price: $2.12346e+08
    

    Note the format of the numbers output for the total price. This format is called exponential notation. For more information on exponential notation, see section: 4.1.2: Exponential Notation.

  4. Let us correct the formatting of the total price. Enter the following code before the statement that prints the total price:
    cout << fixed             // fixed notation, not scientific
         << setprecision(2);  // show 2 decimal places
    

    These statements are referred to as the "magic formula" because they for C++ to output statements in a "standard" format. Note what each statement accomplishes. For more information, see section: 4.1.3: Decimal Formatting.

  5. Compile and run your program again and verify the output looks like:
    Enter the product name: Boeing_777
    Price of the Boeing__777: 212345678
    Total price: $212345678.00
    
  6. Let us add a constant that we will use later in our program. Enter the following code after the magic formula and before the statement that prints the total price:
    const int PERCENT = 100;
    

    A constant variable (or constant) is a variable that cannot change after being assigned a value. Using a constant lets us avoid using a vague number. For more information, see section: 4.1.4: Constants and Magic Numbers.

  7. Now we will add sales tax to the price of the product. Enter the following code after the constant and before the statement that prints the total price:
    double taxRate = 0;
    cout << "Enter sales tax rate (%): ";
    cin >> taxRate;
    double tax = price * taxRate / PERCENT;
    price += tax;
    

    Notice the last statement: price += tax;. This is an alternate way to code the statement: price = price + tax;. For more information, see section: 4.1.5: Assignment Operators.

  8. Compile and run your modified program and verify the output looks like:
    Enter the product name: iPod_nano
    Price of the iPod_nano: 89.50
    Enter sales tax rate (%): 9.5
    Total price: $98.00
    
  9. Now we will find the whole dollars and cents of the amount to demonstrate casting. Enter the following code after the statement that prints the total price and before the return statement:
    int dollars = (int) price;
    cout << "In whole dollars: $" << dollars << endl;
    

    Notice the (int) in the first statement. This is known as a type cast or just cast. For more information, see section: 4.1.6: Type Casting.

  10. Compile and run your modified program and verify the output looks like:
    Enter the product name: iPod_nano
    Price of the iPod_nano: 89.50
    Enter sales tax rate (%): 9.5
    Total price: $98.00
    In whole dollars: $98
    
  11. Submit your program source code to Blackboard as part of assignment 4.
  12. Also, work through the examples in section: 4.1.7: Arithmetic Precision and Range.

Completed Program

Once you are finished, your source code should look like the following (excluding comments):

As time permits, read the following sections and be prepared to answer the Check Yourself questions in the section: 4.1.8: Summary.

Listing of price.cpp

4.1.5: Assignment Operators

  • As we discussed before, we assign values to variables using an equal (=) sign
    int sum = 0;
  • However, the equal sign is really an assignment operator and does not denote equality
  • Thus, unlike math, you can have the same variable on both sides of an equals sign:
    int sum = 25;    // initialize sum to 25
    sum = sum + 10;  // add to sum
    
  • Note that the value of the variable is changed in the second line
  • Reading variables from memory does not change them
  • Values placed into a variable replace (overwrite) previous values:

    Assigning a value to a variable

Shortcut Assignment Operators

  • We can use additional operators to calculate values and assign them to the variable on the left all in one statement
    • Known as shortcut assignment operators
  • The general syntax is:
    variable op= expression;
  • Where op is one of the five arithmetic operators: +, -, *, /, %
  • For example, the following two statements create the same result:
    x = x + 3;
    x += 3;
    
  • Shown below are the assignment operators with examples of how they are used

Summary of Assignment Operators

Operator Description Example Equivalent To
= Assigns the value of the expression on the right to the variable on the left x = 3  
+= Adds the expression on the right to the variable on the left x += 3 x = x + 3
-= Subtracts the expression on the right from the variable on the left x -= 3 x = x - 3
*= Multiplies the expression on the right to the variable on the left and saves the result in the variable on the left x *= 3 x = x * 3
/= Divides the variable on the left by the expression on the right and saves the result in the variable on the left x /= 3 x = x / 3
%= Calculates the remainder from dividing variable on the left by the expression on the right and saves the result in the variable on the left x %= 3 x = x % 3

Increment and Decrement Operators

  • Another arithmetic shortcut is the increment and decrement operators
  • The increment operator (++) adds 1 to a variable's value
  • Preincrement adds 1 before returning the value of a variable
    ++sum;
  • Post-increment returns the current value of variable then adds 1
    sum++;
  • The decrement operator works like the increments operator, except it subtracts 1 from the variable
  • For instance:
    --sum
    sum--
    
  • Pre- and post- increment matters when the operation is part of a larger expression
  • For example, consider the code:
    int x = 5;
    int y = x++;
    cout << "x=" << x << " y=" << y;
    
  • You may expect y to be 6 after this code executes
  • Instead, y has the value of 5
  • The reason is that ++ after a variable (post-increment) is equivalent to:
    y = x;
    x = x + 1;
    
  • On the other hand, ++ before a variable (pre-increment) is equivalent to:
    x = x + 1;
    y = x;
    

4.1.6: Type Casting

Cast: change the data type of the returned value of an expression

  • Recall that different data types are stored in different forms
  • Sometimes you need to change from one form to another
  • For example: arithmetic adding a double and an int value
  • C++ will automatically cast one value to another
    • Known as implicit casting or type coercion
  • Programmers can also explicitly cast data types
  • Explicit casting changes the data type for a single use of the variable
  • Precede the variable name with the new data type in parentheses:
    (dataType) variableName
    
  • The type is changed only for the single use of the value
  • For example:
    double x = 2.99999;
    x = (int) x;
    cout << x << endl;
    
  • The value of x is converted from type double to int before assigning the converted value to x
  • However, x remains a type double and the cast only applies to a single use of x
  • The above example shows a common use of casting -- removing the decimal part of a floating-point number
  • Note that the decimal portion of the number is truncated and NOT rounded
  • Decimal part is lost (discarded, ignored, thrown away)
  • Another use is to convert an int to a double when dividing two int numbers and a decimal result is desired
  • For example:
    double x = (double) 9 / 5;
    cout << x << endl;
    
  • Still another use is to prevent compiler warnings
  • For example:
    double x = 2.3;
    int n = x;
    cout << n << endl;
    
  • The above may cause a compiler warning with the settings we use:
    warning: converting to `int' from `double'
  • To remove the warning, we use a cast:
    double x = 2.3;
    int n = (int) x;
    cout << n << endl;
    
  • This tells the compiler that you intended to convert from double to int

New Style Casting

  • C++ has many styles of casting
  • Newer style of casting is of the form:
    static_cast<toType>(expression)
  • For example:
    int x = 9;
    int y = 2;
    double ans = x / static_cast<double>(y)
    

Example Application Using Casting: cast.cpp

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

int main() {
    double input;
    cout << "Enter hours: ";
    cin >> input;

    int hours = (int) input; // prevents warning
    int minutes = (int) ((input - (int) input) * 60);
    cout << "In hours and minutes, this is "
         << hours << ":" << minutes << endl;
    return 0;
}

4.1.7: Arithmetic Precision and Range

  • There are only a finite set of numbers in numerical data types
  • This can lead to problems for the unwary

Integer Overflow

  • What happens when an integer is too big for its type?
    cout << "Big number: ";
    cout << 2147483647 + 1 << endl;
    cout << "Small number: ";
    cout << -2147483647 - 2 << endl;
    
  • The number "wraps around" from the highest number to the lowest
  • You must be careful that your program will not go beyond the range of its data types
  • Cant't sleep: from xkcd

More Integer Types

  • To increase the range, C++ has the long data type
  • Originally, the long data type was 32 bits while the int was 16 bits
  • However, with the development of 32 bit computers, the int value was extended to 32 bits but the long was left at 32 bits
  • Thus, at the present time, int and long are the same size on most computers
  • In addition, C++ has unsigned integer types you can use to change the range
  • Rather than integer ranges from -2147483647 to 2147483647, unsigned int ranges from 0 to 4294967295

Floating-Point Precision and Range

  • Floating-point numbers are not exact representations of real numbers
  • Rounding errors occur in repeated calculations
  • Type double has about twice the precision of type float
  • However, even type double can have rounding errors
    cout.precision(17);
    cout << .8F + .1F << endl;
    cout << .8 + .1 << endl;
    
  • When floating point numbers get too large, they are set to inf
  • For instance:
    cout << 2E38F + 2E38F << endl;
  • Similarly, when numbers are too small they are set to 0.0

The Moral

  • Integer and floating-point data types work well most of the time
  • However, if you work with large positive or negative integers, you must be sure you do not exceed the range of the data type
  • Also, floating-point numbers have limited precision
  • When math operations are performed repeatedly, they can become less precise
  • Thus you must be careful of precision when using floating-point numbers

More Information

4.1.8: Summary

  • In this section we discussed more details about programming with numbers
  • When floating-point numbers get very large or very small, C++ displays them using exponential (scientific) notation
  • cout includes special functions to specify the output of type double
  • The following magic formula lets us display numbers with 2 decimal places:
    cout.setf(ios::fixed);     // fixed notation, not scientific
    cout.setf(ios::showpoint); // show decimal point
    cout.precision(2);         // show 2 decimal places
    
  • Constants are a variable that cannot change after it is first assigned a value
  • Constants are often used to apply meaningful names to numbers
  • Another reason to use named constants is that it is easier to change the value of the number
  • C++ has assignment variations of the form:
    variable <op>= expression;
  • C++ will automatically cast data of one type to another when necessary
  • However, you can explicitly cast values to a different type.
  • You must explicitly cast when C++ does not perform as you want.
  • Not all numbers can be represented accurately by primitive C++ types
  • Integer values have a limited range
  • If your program assigns values too high or too low, integers wrap around
  • Floating-point numbers usually have enough range
  • However, they often suffer from lack of precision
    cout.precision(17);
    cout << .8F + .1F << endl;
    cout << .8 + .1 << endl;
    
  • Type double has about twice the precision of type float
  • When floating point numbers get too large, they are set to inf
  • Similarly, when too small they are set to 0.0

Check Yourself

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. How are very large or very small numbers floating point numbers formatted by default when displayed with cout? (4.1.2)
  2. What is the "magic formula" for displaying numbers in decimal notation? (4.1.3)
  3. What is the purpose of each line of the magic formula? (4.1.3)
  4. What is the code to declare a constant double named BIG_NUM and assign it a value of 100,000? (4.1.4)
  5. What is an equivalent statement for each of the following shortcut assignments? (4.1.5)
    1. a += b;
    2. a -= b;
    3. a *= b;
    4. a /= b;
    5. a %= b;
  6. How many ways can you add the integer 1 to a variable named index? List each way. (4.1.5)
  7. Which is a valid typecast? (4.1.6)
    1. a(int)
    2. int:a;
    3. (int)a;
    4. to(int, a);
  8. How can you truncate the decimal part of double variable? (4.1.6)
  9. What happens when you increase the value of a signed integer beyond its range? (4.1.7)
  10. How many digits that can be accurately stored in a type float? double? (4.1.7)
  11. What is the output of the following code fragment? Why? (4.1.7)
    cout.precision(17);
    double r = sqrt(2);
    if (r * r == 2) {
        cout << "sqrt(2) squared is 2\n";
    } else {
        cout << "sqrt(2) squared is not 2 but "
             << (r * r) << endl;
    }
    

4.2: More About Selections

Learner Outcomes

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

  • Recognize the correct ordering of tests in multiple branches
  • Program conditions using Boolean operators and variables
  • Avoid some common pitfalls when creating test conditions

4.2.1: Multiple Alternatives

  • By using collections of if-else statements, a program can distinguish between multiple alternatives
  • For example, consider the following example where a user enters the name of a coin, and the program displays the value

Program Converting Coin Names to Values

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

int main() {
    cout << "Enter coin name: ";
    string name;
    cin >> name;
    double value = 0;

    if (name == "penny") {
        value = 0.01;
    } else if (name == "nickel") {
        value = 0.05;
    } else if (name == "dime") {
        value = 0.10;
    } else if (name == "quarter") {
      value = 0.25;
    } else {
        cout << name << " is not a valid coin name\n";
    }
    cout << "Value = " << value << "\n";

    return 0;
}

Choosing Between Alternatives

  • This program has five alternatives to choose from:
    1. "penny"
    2. "nickel"
    3. "dime"
    4. "quarter"
    5. erroneous input
  • Note that the order that the alternatives are checked is unimportant
  • We can follow the alternatives in the flowchart shown below

Flowchart of Multiple Alternative for Converting Coins to Values

Flowchart of multiple alternatives

4.2.2: When Order Matters

  • In some cases, the order of the tests is important
  • For example, look at the following program from the textbook that displays a description of the likely impact of an earthquake based on its magnitude on the Richter scale

Program Showing Multiple Alternatives Where Order Matters

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

int main() {
    cout << "Enter a magnitude on the Richter scale: ";
    double richter;
    cin >> richter;

    if (richter >= 8.0) {
        cout << "Most structures fall\n";
    } else if (richter >= 7.0) {
        cout << "Many buildings destroyed\n";
    } else if (richter >= 6.0) {
        cout << "Many buildings considerably damaged, "
             << "some collapse\n";
    } else if (richter >= 4.5) {
        cout << "Damage to poorly constructed buildings\n";
    } else if (richter >= 3.5) {
        cout << "Felt by many people, no destruction\n";
    } else if (richter >= 0) {
        cout << "Generally not felt by people\n";
    } else {
        cout << "Negative numbers are not valid\n";
    }

    return 0;
}

Order Is Important

  • Note that the order of the tests is important to ensure that the right results are printed
  • If we rearranged the order of the if-else statements, we would get the wrong results
  • For example, if we reversed the order of the tests:
    if (richter >= 0) { // tests in wrong order
        cout << "Generally not felt by people\n";
    } else if (richter >= 3.5) {
        cout << "Felt by many people, no destruction\n";
    } else if (richter >= 4.5) {
        cout << "Damage to poorly constructed buildings\n";
    } else if (richter >= 6.0) {
        cout << "Many buildings considerably damaged, "
             << "some collapse\n";
    } else if (richter >= 7.0) {
        cout << "Many buildings destroyed\n";
    } else if (richter >= 7.0) {
        cout << "Most structures fall\n";
    } else {
        cout << "Negative numbers are not valid\n";
    }
    
  • This does not work because all values meet the first condition
  • Every other test will never be attempted

Importance of Using if-else-if Structure

  • Note that we cannot remove the else portion of the structure like shown below:
    if (richter >= 7.0) { // Does not use else
        cout << "Most structures fall\n";
    }
    if (richter >= 7.0) {
        cout << "Many buildings destroyed\n";
    }
    if (richter >= 6.0) {
        cout << "Many buildings considerably damaged, "
             << "some collapse\n";
    }
    if (richter >= 4.5) {
        cout << "Damage to poorly constructed buildings\n";
    }
    if (richter >= 3.5) {
        cout << "Felt by many people, no destruction\n";
    }
    if (richter >= 0) {
        cout << "Generally not felt by people\n";
    }
    if (richter < 0) { {
        cout << "Negative numbers are not valid\n";
    }
    
  • The conditions must be exclusive and we need the else-if conditions to ensure exclusivity
  • Independent if statements may cause a single input to print several messages

4.2.3: switch Statements

  • The switch statement provides an alternative to an if-else-if chain
  • Executes a section of code depending on value of a variable
  • The general syntax is:
    switch (integerExpression) {
       case label1:
          statements
          break;
       case label2:
          statements
          break;
       ...
       case labeln:
          statements
          break;
       default:
          statements
    }
    
  • Where:
    • integerExpression: an arithmetic expression that resolves to an integer number
    • labelx: a numeric constant
    • statements: the statements to execute when the condition is met
  • Any number of case labels can be placed in any order
  • Any value that does not match starts executing with the statement after default
  • Execution continues until the end of the switch statement or a break statement
  • The break statement causes an immediate exit from the switch statement
  • Just as case identifies possible starting points, break determines end points

Example Program Using a switch Statement

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

int main() {
    int shippingOption = 0;
    cout << "Enter a shipping option (1-3): ";
    cin >> shippingOption;

    switch (shippingOption - 1) {
        case 0:
            cout << "Parcel post delivery in two weeks.\n";
            break;
        case 1:
            cout << "UPS delivery in three days.\n";
            break;
        case 2:
            cout << "Fed-Ex overnight delivery.\n";
            break;
        default:
            cout << "It may never get there!\n";
    }
    cout << "Ship it!\n";

    return 0;
}

When to Use switch Statements

  • You can only use switch statements with integer expressions and each case must be a constant
  • In addition, switch statements only work for exact matches (==)
  • Thus, switch statements are inherently less useful than if-else statements
  • Also, the syntax is no clearer than if-else statements
  • Note that there is a reason for the limitations of the switch statement
  • Many years ago a compiler could generate more efficient code (using jump tables or binary searches) only within the limitations of the switch statement
  • However, modern compilers are quite capable of optimizing if-else statements to the same degree
  • Thus, we have no reason to ever use a switch statement, depending on your compiler
  • On the other hand, there are reasons to avoid using a switch statement
  • Every branch of the switch statement must be terminated by a break statement
  • If the break statement is missing, the program falls through and executes the next case without testing
  • There are rare uses for this fall through behavior, such as printing the words for the song, The Twelve Days of Christmas
  • However, according to a study by Peter van der Linden, reported in his book, Expert C Programming, p. 38, the falling through behavior is needed less than 3% of the time
  • Thus, the default behavior is wrong 97% of the time
  • Forgetting to type the break statement is a very common error and the source of many bugs
  • So one has to ask oneself, "Why use an inferior programming statement that causes more problems than it solves?"

4.2.4: Nested Branches

  • Nested if-else statements can be used when there are two (or more) levels of decision making.
  • For example, consider the following two tax tables from 1992 shown in the textbook on p. 252
  • There is a different table for each marital status (decision 1)
  • Once you have found the right table, your are taxed differently according to your income (decision 2)

Tax Table if Single

If your status is Single and if the taxable income is over but not over the tax is of the amount over
$0 $21,450 15% $0
$21,450 $51,900 $3,217.50 + 28% $21,450
$51,900 $11,743 + 31% $51,900

Tax Table if Married

If your status is Married and if the taxable income is over but not over the tax is of the amount over
$0 $35,800 15% $0
$35,800 $86,500 $5,370.00 + 28% $35,800
$86,500 $19,566.00+ 31% $86,500

Programming Two-Level Decisions

  • When we program this two-level decision process, we often use two levels of if statements
  • We say the income test is nested inside the test for filing status
  • We can see this two-level decision in the flowchart shown below
  • Also, we can examine and run the program from the code shown below
  • Note that more complicated decisions may require deeper levels of nesting

Flowchart of Two-level Tax Decision Process

Flowchart of nested branches

Program Computing Single and Married Tax Rates

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
using namespace std;

int main() {
    const double SINGLE_LEVEL1 = 21450.00;
    const double SINGLE_LEVEL2 = 51900.00;

    const double SINGLE_TAX1 = 3217.50;
    const double SINGLE_TAX2 = 11743.50;

    const double MARRIED_LEVEL1 = 35800.00;
    const double MARRIED_LEVEL2 = 86500.00;

    const double MARRIED_TAX1 = 5370.00;
    const double MARRIED_TAX2 = 19566.00;

    const double RATE1 = 0.15;
    const double RATE2 = 0.28;
    const double RATE3 = 0.31;

    double income;
    double tax;

    cout << "Please enter your income: ";
    cin >> income;

    cout << "Please enter s for single, m for married: ";
    string marital_status;
    cin >> marital_status;

    if (marital_status == "s") {
        if (income <= SINGLE_LEVEL1) {
            tax =  RATE1 * income;
        } else if (income <= SINGLE_LEVEL2) {
            tax = SINGLE_TAX1
                + RATE2 * (income - SINGLE_LEVEL1);
        } else {
            tax = SINGLE_TAX2
                + RATE3 * (income - SINGLE_LEVEL2);
        }
    } else {
        if (income <= MARRIED_LEVEL1) {
            tax =  RATE1 * income;
        } else if (income <= MARRIED_LEVEL2) {
            tax = MARRIED_TAX1
                + RATE2 * (income - MARRIED_LEVEL1);
        } else {
            tax = MARRIED_TAX2
                + RATE3 * (income - MARRIED_LEVEL2);
        }
    }
    cout << "The tax is $" << tax << "\n";

    return 0;
}

4.2.5: Boolean Variables

  • Sometime you need to evaluate a logical condition in one part of a program and use it elsewhere
  • To store a condition that can only be true or false, you use a Boolean variable
  • Boolean variables are named after George Boole (1815-1864), a pioneer in the study of logic
  • You specify a Boolean variable using the bool type, which can hold just one of two values: true or false
    bool truth = true;
    bool lies = false;
    
  • Question: How does George Boole order lunch? (see here)
  • Question: What type of tests does George Boole give? (answer)
  • One possible use for a Boolean variable is for printing the result of a test condition as shown below

Example Application Using a Boolean Variable

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;

// For testing
int main() {
    double num;
    cout << "Enter a whole number: ";
    cin >> num;

    bool test = (num >= 0);
    cout << boolalpha; // output true or false for bool
    cout << "The test evaluated to: " << test << endl;
    if (test) {
        cout << "The number was 0 or positive\n";
    } else {
        cout << "The number was negative\n";
    }

    return 0;
}

4.2.6: Boolean Operators

  • When you make complex test conditions, you often need to combine Boolean values
  • An operator that combines Boolean values is called a logical operator or Boolean operator
  • C++ has several logical operators, but you only need to use three to create any possible test condition
  • These three operators are and, or and not, which are discussed below
  • These logical operators are traditionally written as && (and), || (or) and ! (not)
  • Both variants are legal under ANSI C++
  • The words are easier to read but many C++ programmers still use the older form

and (&&) Operator

  • One such operator is and, which is traditionally spelled && in C++
  • For example, the following is true if guess != GUESS1 and guess != GUESS2:
    ((guess != GUESS1) && (guess != GUESS2))
    
  • When two boolean expressions are connected using && the whole expression is true only if both conditions are true
  • However, if either condition is false the whole expression is false
  • These combinations are shown in the following truth table

    and (&&) Operator Truth Table
    If expr1 is... And expr2 is... Then expr1 and expr2 is... Example Result
    true true true 5 < 10 and 5 > 2 true
    true false false 5 < 10 and 5 < 2 false
    false true false 5 > 10 and 5 > 2 false
    false false false 5 > 10 and 5 < 2 false

or (||) Operator

  • Also, you can combine two boolean expressions using the or operator, traditionally spelled || in C++
  • For example, the following is true if GUESS1 == guess or GUESS2 == guess:
    ((GUESS1 == guess) || (GUESS2 == guess))
    
  • When two boolean expressions are connected using || the whole expression is true if either condition is true
  • Only if both conditions are false is the entire expression false
  • These combinations are shown in the following truth table

    or (||) Operator Truth Table
    If expr1 is... || expr2 is... Then expr1 or expr2 is... Example Result
    true true true 5 < 10 or 5 > 2 true
    true false true 5 < 10 or 5 < 2 true
    false true true 5 > 10 or 5 > 2 true
    false false false 5 > 10 or 5 < 2 false

not Operation

  • Additionally, you can invert any expression using not operator, traditionally spelled ! in C++
  • To use it, place the entire expression in parenthesis and place the ! operator in front
  • For example, to allow two guesses, we can negate our previous example:
    !((GUESS1 == guess) || (GUESS2 == guess))
    
  • These combinations are shown in the following truth table

    not (!) Operator Truth Table
    If expr is... Then ! expr is... Example Result
    true false !true false
    false true !(5 < 2) true

Parenthesis

  • Remember that a boolean expression in an if statement must be enclosed in parenthesis
  • Thus, an if statement with && might look like:
    if ((guess != GUESS1) && (guess != GUESS2))
  • Note that relational operators have a higher precedence than logical operators
  • Thus, we can remove the inner parenthesis without affecting the meaning:
    if (guess != GUESS1 && guess != GUESS2)
  • However, if using parenthesis is easier to understand then use the extra parenthesis

Confusing && and || Conditions

  • Many people confuse && and || conditions, especially when learning about logical operators
  • A value lies between 0 and 100 if the value is at least 0 and at most 100
  • A value is outside that range if it is less than 0 or greater than 100
  • There is no golden rule; you have to think carefully and test your conditions

Example Program with Logical Operators

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;

int main() {
    const int ANSWER1 = 7;
    const int ANSWER2 = 8;

    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 (ANSWER1 == guess || ANSWER2 == guess) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
        cout << "Try again: ";
    }

    return 0;
}

More Information

Exercise 4.2

In this exercise we test multiple alternatives in a program. As an example, we will calculate a student's letter grade 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

Specifications

  1. Copy the following program into a text editor, save it as grader.cpp, and then compile and run the starter program to make sure you copied it correctly.
    #include <iostream>
    using namespace std;
    
    int main() {
        // Enter your code here
    
        return 0;
    }
    
  2. Add code to get user input into a variable named score of type double. When you run the program after adding this code, the output should look like:
    Enter a score: 95.7
    

    Make sure you declare the variable with a compatible data type. Note that the underlined numbers above shows what the user enters and is not part of your code. For more information see section 2.4.6: Input and Output.

  3. First we will look at a series of if statements and see that if statements alone are not enough to solve this problem. Copy the following into your program after the input statements:
    string grade;
    if (score >= 90) {
        grade = "A";
    }
    if (score >= 80) {
        grade = "B";
    }
    if (score >= 70) {
        grade = "C";
    }
    if (score >= 60) {
        grade = "D";
    }
    if (score < 60) {
        grade = "F";
    }
    cout << grade << endl;
    

    Compile and run your modified program. There is a logic problem with this code. Each test condition needs to work over a range of values rather than with a single value.

  4. One way to correct the problem is to nest an if statement inside of another if statement. To see how this works, modify your code to add nested if statements as shown below:

    Nested if statements

    To test the range, the outer if statement tests the lower condition and the inner if statement tests the upper condition. For more information see section 4.2.4: Nested Branches.

  5. Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    Enter a score: 80
    B
    

    Run your program a few times with different score to verify that any score displays the correct letter grade.

  6. The reason for using nested if statements is often to test multiple conditions. Often, a better alternative is to use Boolean operators like && and ||. To see how Boolean operators work, modify your code to add nested if statements as shown below:

    Testing with logical operators

    For more information see section 4.2.5: Logical Operators.

  7. Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    Enter a score: 80
    B
    

    Run your program a few times with different score to verify that any score displays the correct letter grade.

  8. Perhaps the most elegant solution is to nest an if statement in the else clause of the preceding if. Modify the series of if statements to include an else clause as shown below:

    if-else statements

    We are nesting if statements in the else clause. Nesting in the else clause makes each test condition of the if statement exclusive of the others because each test condition eliminates all the preceding conditions. Thus, in this scenario the order is important. For more information see section 4.2.2: When Order Matters.

  9. Compile and run your modified program to make sure you made the changes correctly. When you run the program, the output should look like:
    Enter a score: 80
    B
    

    Run your program a few times with different score to verify that any score displays the correct letter grade.

  10. Submit your final program source code to Blackboard as part of assignment 4.

As time permits, read the following sections and be prepared to answer the Check Yourself questions in the section: 4.2.8: Summary.

4.2.7: 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

Using = Instead of ==

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

4.2.8: Summary

  • By using collections of if-else statements, a program can distinguish between multiple alternatives
  • Sometimes the order of statements is important for our program to work correctly
  • We must think carefully and test our conditions rigorously
  • Nested if-else statements can be used when there are two (or more) levels of decision making.
  • We looked at an example of tax tables, filing as single or married
  • To create conditions with multiple cases, we looked at using logical operators: &&, || and !
  • We looked at some examples including:
    ((guess != GUESS1) && (guess != GUESS2))
    ((GUESS1 == guess) || (GUESS2 == guess))
    !((GUESS1 == guess) || (GUESS2 == guess))
    
  • Unfortunately, you can write things in C++ that should be incorrect but end up working for some obscure reason
  • These types of errors are often very difficult to find
  • One common mistake is to use = when you mean to use ==
    if (guess = 7)
  • Which should be written as:
    if (guess == 7)
  • Another common problem is trying to use a string of inequalities without a logical operator separating each condition, like:
    if (a < b < c)
  • Which should be written as:
    if (a < b && b < c)
  • Another common error is trying to use logical operators without enough operands:
    if (guess == 7 || 8)
  • Which should be written as:
    if (guess == 7 || guess == 8)

Check Yourself

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. True of false? An elegant way to choose among multiple alternatives is to nest if statements in an else clause. (4.2.1)
  2. If score = 85, what is output by the following code fragment? (4.2.1)

    if-else statements

  3. True of false? Order never matters in a sequence of if and else statements. (4.2.2)
  4. What is the difference between if-else if-else and nested if statements? (4.2.2 vs. 4.2.4, answer)
  5. True of false? A switch statement is a more powerful solution to multiple if-else if-else statements (4.2.3)
  6. True of false? You can next if statements within another if statement. (4.2.4)
  7. What date type stores only the values true or false? (4.2.5)
  8. When does an AND (&&) of two or more conditions evaluate to true? (4.2.6)
  9. When does an OR (||) of two or more conditions evaluate to false? (4.2.6)
  10. What is the effect of the NOT (!) operator? (4.2.5)
  11. True of false? A && B is the same as B && A for any Boolean conditions A and B. (4.2.6)
  12. If score = 85, what is output by the following code fragment? (4.2.6)

    Testing with logical operators

  13. How many errors can you spot in the following code fragment? (4.2.7)
    if (person = terrorist) {
        punish_severely();
    } else {
        exit(-1);
    }
    

    Answer and credit for the idea.

  14. What is wrong with the following string of inequalities and how do you correct the code? (4.2.7)
    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";
    }
    
  15. What is wrong with the following string of logical operators and how do you correct the code? (4.2.7)
    int guess;
    cout << "Enter a guess: ";
    cin >> guess;
    if (guess == 7 || 8) {
        cout << "*** Correct! ***\n";
    } else {
        cout << "Sorry, that is not correct.\n";
    }
    

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
  • Discuss the usual parts of a loop
  • Describe what is meant by a main loop

4.3.1: Simple Loops

  • Sometimes we want to repeat a section of code
  • For instance, we may want to let a user run our program multiple times
  • When we want to repeat a section of code, we use a loop statement
  • A 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 through the loop
  • To set up the test condition, we write initialization code
  • In general, loops have three parts to them
    • 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

4.3.2: Coding while Statements

  • 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
  • Syntax:
    while (test) {
       statement1
       statement2
       ...
    }
    
  • Where:
    • test: the test condition to evaluate
    • statementX: the statements to execute while the test remains true
  • For example:
    string repeat = "y";
    while ("y" == repeat) {
        // ... statements to repeat
        cin >> repeat;
    }
    
  • The following flow chart shows how the while loop operates
  • We will explore the while loop in the next exercise

Diagram of while Loop Operation

While loop flow chart

4.3.3: 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

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;
    }
    
  • 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
  • For the acceptable styles for this course see: Curly Braces

Exercise 4.3

In this exercise we use a loop to allow a user to repeat a program.

Specifications

  1. 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;
    }
    
  2. 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.

  3. 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. For more information, see section: 4.3.2: Coding while Statements.

  4. 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 the repeat 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. For more information, see section: 4.3.3: Understanding the while Loop.

  5. Formatting a loop is important. Indent all the code within the curly braces of the while loop. For more information, see Formatting the Code in the section: 4.3.3: Understanding the while Loop.
  6. 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";
    
  7. 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
    
  8. Submit your program source code to Blackboard as part of assignment 4.

Completed Program

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

Completed exercise

Check Yourself

As time permits, be prepared to answer these questions. You can find more information by following the links after the question.

  1. What is the purpose of a loop? (4.3.1)
  2. What are the three parts of any loop? (4.3.1)
  3. What is the syntax of a while statement? (4.3.2)
  4. What is the purpose of a loop test condition? (4.3.3)
  5. What is the purpose of loop initialization code? (4.3.3)
  6. What part of a loop is repeated? (4.3.3)
  7. What is meant by the term main programming loop? (4.3.4)

4.3.4: Generalizing the Main Loop

  • We can generalize the main loop of our example
  • Implementation can be different from one program to another
  • However, the basic structure is the same for most programs

Program Flow with a Main Loop

Main loop flow

Notes on the Program Flow

  • Set Up (statements before the loop)
    • Declare and initialize variables
    • Provide instructions
  • Repeated steps (loop body)
    • Get User Input
    • Update Variables
    • Update Display
    • Program Done?
      • Check if the program is completed
      • Often the user decides to exit
      • Change variables in the test condition of the loop
  • Shut Down (statements after the loop)
    • Provide the user any final information
    • End the program

4.3.5: 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?
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;
}

4.3.6: Summary

  • Loops execute a block of code repeatedly
  • To stop (terminate) a loop you set a test condition
  • General loop structure:
    • Initialization code
    • Test condition -- evaluated during the loop
    • Loop body with some way to change the test condition
  • One loop statement we looked at is the while loop
  • For example:
    string repeat = "y";
    while ("y" == repeat) {
        // ... statements to repeat
        cin >> repeat;
    }
    
  • Most programs have a main loop
  • Statements inside the loop repeat until the program exits
  • Several problems can occur when using a loop including:
    • Infinite loops: loops that "never" end
    • Missing curly braces
    • Empty statements

Wrap Up

Due Next:
A3-Three Easy Programs (3/4/10)
A4-Making Seletections (3/11/10)
  • 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.
Home | Blackboard | Day Schedule | Eve Schedule
Syllabus | Help | FAQ's | HowTo's | Links
Last Updated: April 09 2010 @15:08:19