What We Will Cover
Continuations
Homework Questions?
- Who is thinking about pair programming?
- Pair programming is worth extra credit
- Success Strategies
Homework Discussion Questions
- How "natural" did it feel to use arithmetic in C++?
- How many
if-statements did you need to solve the playing cards program?
- Did you run into any problems developing the Mad Libs program?
- 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';
^ top
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
|
^ top
4.1.1: Numbers and Arithmetic
^ top
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?
^ top
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
^ top
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
More Information
^ top
Exercise 4.1
In this exercise we explore some additional numeric features of C++.
Specifications
- 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;
}
|
- 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.
- 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.
- 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.
- 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
- 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.
- 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.
- 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
- 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.
- 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
- Submit your program source code to Blackboard as part of assignment 4.
- 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.

^ top
4.1.5: Assignment Operators
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
^ top
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
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;
}
|
^ top
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
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
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
^ top
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.
- How are very large or very small numbers floating point numbers formatted by default when displayed with
cout? (4.1.2)
- What is the "magic formula" for displaying numbers in decimal notation? (4.1.3)
- What is the purpose of each line of the magic formula? (4.1.3)
- What is the code to declare a constant
double named BIG_NUM and assign it a value of 100,000? (4.1.4)
- What is an equivalent statement for each of the following shortcut assignments? (4.1.5)
a += b;
a -= b;
a *= b;
a /= b;
a %= b;
- How many ways can you add the integer 1 to a variable named
index? List each way. (4.1.5)
- Which is a valid typecast? (4.1.6)
a(int)
int:a;
(int)a;
to(int, a);
- How can you truncate the decimal part of double variable? (4.1.6)
- What happens when you increase the value of a signed integer beyond its range? (4.1.7)
- How many digits that can be accurately stored in a type
float? double? (4.1.7)
- 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;
}
^ top
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
|
^ top
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:
- "penny"
- "nickel"
- "dime"
- "quarter"
- 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
^ top
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
^ top
4.2.3: switch Statements
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?"
^ top
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
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;
}
|
^ top
4.2.5: Boolean Variables
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;
}
|
^ top
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
or (||) Operator
not Operation
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
^ top
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
- 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;
}
- 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.
- 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.
- 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:

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

For more information see section 4.2.5: Logical Operators.
- 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.
- 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:

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.
- 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.
- 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.
^ top
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";
}
^ top
4.2.8: Summary
Check Yourself
Answer these questions to check your understanding. You can find more information by following the links after the question.
- True of false? An elegant way to choose among multiple alternatives is to nest
if statements in an else clause. (4.2.1)
- If
score = 85, what is output by the following code fragment? (4.2.1)

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

- 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.
- 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";
}
- 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";
}
^ top
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
|
^ top
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++:
- We will start with the simplest of the three -- the
while statement
^ top
4.3.2: Coding while Statements
Diagram of while Loop Operation

^ top
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
^ top
Exercise 4.3
In this exercise we use a loop to allow a user to repeat a program.
Specifications
- Copy the following program into a text editor, save it as
loopy.cpp, and then compile and run the starter program to make sure you copied it correctly.
#include <iostream>
using namespace std;
int main() {
int guess = 0;
cout << "I'm thinking of a number between"
<< " 1 and 10.\nCan you guess it?\n\n"
<< "Enter your guess: ";
cin >> guess;
if (7 == guess) {
cout << "*** Correct! ***\n";
} else {
cout << "Sorry, that is not correct.\n";
cout << "Try again.\n";
}
return 0;
}
- Add the following code after the statement
int guess = 0; and before the cout statement:
string repeat = "y";
This is the initialization code that we will use for the test condition that comes next.
- We want to repeat all the rest of the code in our program. For this we need to add a
while statement such as:
while ("y" == repeat) {
// Place the rest of the code after the initialization
// and before the return 0 between these curly braces.
}
Statements inside the curly braces repeat while the test condition in the parenthesis, ("y" == repeat), evaluates to true. For more information, see section: 4.3.2: Coding while Statements.
- 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.
- 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.
- As a final part of our program, we add the infamous phrase: "Game Over". Add the following statement after the closing curly brace of the while loop:
cout << "Game over\n";
- Compile and run your program again and verify the output looks like:
I'm thinking of a number between 1 and 10.
Can you guess it?
Enter your guess: 3
Sorry, that is not correct.
Try again.
Do you want to play again? (y/n) y
I'm thinking of a number between 1 and 10.
Can you guess it?
Enter your guess: 7
*** Correct! ***
Do you want to play again? (y/n) n
Game over
- Submit your program source code to 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.

Check Yourself
As time permits, be prepared to answer these questions. You can find more information by following the links after the question.
- What is the purpose of a loop? (4.3.1)
- What are the three parts of any loop? (4.3.1)
- What is the syntax of a
while statement? (4.3.2)
- What is the purpose of a loop test condition? (4.3.3)
- What is the purpose of loop initialization code? (4.3.3)
- What part of a loop is repeated? (4.3.3)
- What is meant by the term main programming loop? (4.3.4)
^ top
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
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
^ top
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;
}
|
^ top
4.3.6: Summary
^ top
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.
^ top
Home
| Blackboard
| Day Schedule
| Eve Schedule
Syllabus
| Help
| FAQ's
| HowTo's
| Links
Last Updated: April 09 2010 @15:08:19
|