Chapter 3: Control Flow
Dr. Yomna Safaa El-Din
Contents
• The if statement
• Loops
• Random numbers
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
The if statement
• The if statement is used to implement a decision.
• It has two parts: a test and a body.
• Example:
if (area < 0)
cout << "Error: Negative area.\n";
• Multiple statements can be grouped together in a block statement by
enclosing them in braces { }:
if (area < 0)
{
cout << "Error: Negative area.\n";
return 1;
}
The if statement
The if statement (example)
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main()
{
double area;
cout << "Please enter the area of a square: ";
cin >> area;
if (area < 0)
{
cout << "Error: Negative area.\n";
return 1;
}
/* now we know that area is >= 0 */
double length = sqrt(area);
cout << "The side length of the square is "
<< length << "\n";
return 0;
}
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
The if/else statement
• The if/else consists of a condition of two alternatives.
• The first condition is performed is the condition is true.
• The second condition is performed if the condition is false.
if (area >= 0)
cout << "The side length is " << sqrt(area) << "\n";
else
cout << "Error: Negative area.\n";
The if/else statement
• The if/else statement is a better choice than a pair of if
statements with complementary conditions.
if (area >= 0)
cout << "The side length is " << sqrt(area) << "\n";
else
cout << "Error: Negative area.\n";
if (area >= 0) /* complementary conditions */
cout << "The side length is " << sqrt(area) << "\n";
if (area < 0) /* complementary conditions */
cout << "Error: Negative area.\n";
if statement (common-error)
if (country == "USA")
if (state == "HI")
shipping_charge = 10.00; // Hawaii is more expensive
else // Pitfall!
shipping_charge = 20.00; // as are foreign shipments
double shipping_charge = 5.00; // $5 inside continental U.S.
if (country == "USA")
if (state == "HI")
shipping_charge = 10.00; // Hawaii is more expensive
else // Pitfall!
shipping_charge = 20.00;
double shipping_charge = 5.00;
if (country == "USA")
{
if (state == "HI")
shipping_charge = 10.00;
}
else
shipping_charge = 20.00
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
if statement (selection operator)
test ? value1 : value2
y = (x >= 0) ? x : -x;
Same as:
if (x >= 0) y = x;
else y = -x;
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
Relational Operators
• C++ has six relational operators to implement conditions:
Relational Operators (= vs ==)
Note:
if (x = y) ...
• is legal C++, but it does not test whether x and y are equal.
• Instead, the code sets x to y, and if that value is not zero, the body of
the if statement is executed.
Relational Operators (comparing floating
numbers)
• Floating-point numbers have only a limited precision, and calculations can introduce roundoff errors.
• For example, the following code multiplies the square root of 2 by itself. We expect to get the answer
2:
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 << "\n“;
• Strangely enough, this program displays
• To see what really happens, we need to see the output with higher precision.
• Roundoff errors are unavoidable.
• It does not make sense to compare floating-point numbers exactly.
• Instead, we should test whether they are close enough.
• That is, the magnitude of their difference should be less than some threshold.
More accurately
Relational Operators (strings)
• The relational operators listed above can also be used to compare
strings using lexicological comparison using dictionary order.
• lexicological comparison: corresponding letters are compared until
one of the strings ends or the first difference is encountered.
• If one of the strings ends, the longer string is considered the later one.
• Ex: "car" is less than "cargo“
• If a character mismatch is found, compare the characters to determine which
string comes later in the dictionary sequence.
• Ex: "cargo" is less than "cathode"
Relational Operators (strings)
• The dictionary ordering used by C++ is slightly different from that of a
normal dictionary.
• C++ is
• Case-sensitive
• Sorts characters by listing numbers first, then uppercase characters, then lowercase
characters.
• The space character comes before all other characters
• For example, 1 comes before B, which comes before a.
• The character sort order uses the so-called ASCII code (American Standard
Code for Information Interchange), or one of its extensions (UNICODE)
• ASCII Codes found in Appendix D in Book
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
Input Validation
• Input validation is an application of the if statement that verifies the
user has given reasonable input.
• Example: double area;
cin >> area;
user types "five" and hits return! (Causing cin to fail).
• After every input a good program will test:
if ([Link]())
Input Validation
• The actual input should also be validated, even if the type is correct.
if (area < 0)
• Other strategies:
if (cin)
/* the stream did not fail */
else
/* the stream failed */
if (cin >> x) ...
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
Multiple Alternatives
• By using collections of if/else statements, a program can
distinguish between multiple alternatives.
• Example:
• The user enters the name of a coin, and the program returns the value.
• This program has five alternatives to choose from:
• "penny"
• "nickel"
• "dime"
• "quarter"
• erroneous input
• In this example, the order that the alternatives are checked is unimportant
Multiple Alternatives (Coins Flowchart)
Multiple Alternatives (Coins example)
#include <iostream>
#include <string>
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;
}
Multiple Alternatives (Example 2)
• In some cases, the order of the tests is important.
• Example:
• A program that displays a description of the likely impact of an earthquake
based on its magnitude on the Richter scale.
• The order of the tests ensures that the right results are printed (see following
code).
• Note that the if/else/else structure ensure the alternatives are
exclusive.
• Independent if statements may cause a single input to print several messages.
Multiple Alternatives (Example 2)
#include <iostream>
#include <string>
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;
Multiple Alternatives (switch statement)
• A sequence of if/else/else that compares a single integer value
against several constant alternatives can be implemented as a switch
statement.
switch(digit)
int digit; {
if (digit == 1) digit_name = "one"; case 1: digit_name = "one"; break;
else if (digit == 2) digit_name = "two"; case 2: digit_name = "two"; break;
else if (digit == 3) digit_name = "three"; case 3: digit_name = "three"; break;
else if (digit == 4) digit_name = "four"; case 4: digit_name = "four"; break;
else if (digit == 5) digit_name = "five"; case 5: digit_name = "five"; break;
else if (digit == 6) digit_name = "six"; case 6: digit_name = "six"; break;
else if (digit == 7) digit_name = "seven"; case 7: digit_name = "seven"; break;
else if (digit == 8) digit_name = "eight"; case 8: digit_name = "eight"; break;
else if (digit == 9) digit_name = "nine"; case 9: digit_name = "nine"; break;
else digit_name = ""; default: digit_name = ""; break;
}
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
Nested branches
• Nested if/else statements can be used when there are two (or
more) levels of decision making.
• Example:
if (animal == "cat") {
if (weight > 4)
cout << "fat";
else
cout << "good";
}
else if (animal == "tiger") {
if (weight > 200)
cout << "fat";
else
cout << "good";
}
Contents
• The if statement
• if/else statement
• Selection operator
• Relational Operators
• Input Validation
• Multiple Alternatives
• Nested branches
• Boolean Operations
• Loops
• Random numbers
Boolean Operations
• An operator that combines test conditions is called a logical operator.
• The && (and) operator combines several tests into a new test that
passes only when all the conditions are true.
if (animal == "cat" && weight > 4)
cout << "fat cat";
• The || (or) operator combines two or more
conditions and succeeds if at least one of
the conditions is true.
if (state == "HI" || state == "AK")
shipping_charge = 10.00;
Boolean Operations
• The && and || operators are computed using lazy evaluation.
• The expressions are evaluated from left to right, and evaluation stops
as soon as the truth value is determined.
if ([Link]() || area < 0) cout << "Input error.\n";
if (r >= 0 && -b / 2 + sqrt(r) >= 0) ...
Boolean Operations
• The ! (not) operator takes a single condition and evaluates to true if
that condition is false and to false if that condition is true.
if (![Link]()) quarters = quarters + n;
Boolean Operations (common error)
if (-0.5 <= x <= 0.5) // Error if (x && y > 0) ... // Error
if (-0.5 <= x && x <= 0.5) if (x > 0 && y > 0) ...
Boolean Operations (DeMorgan's Law)
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
Loops
• A loop is a block of code that can be performed repeatedly.
• A loop is controlled by a condition that is checked each time through
the loop.
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
The while loop
• The while statement makes a check before each execution of the
code.
The while loop
• The while statement makes a check before each execution of the
code.
• Example: how long does it take an investment to double?
while( balance < 2 * initial_balance)
{
balance = balance * ( 1 + rate / 100);
year++;
}
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
The for loop
• The most common loop has the form:
• Because this loop is so common, there is a special form for it.
The for loop
• Example (factorial)
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
The do loop
• Sometimes you want to execute the body of a loop at least once and
perform the loop test after the body was executed.
• The do/while loop serves that purpose.
The do loop
• Example (square root)
do
{
xold = xnew;
xnew = (xold + a / xold) / 2;
}
while (fabs(xnew - xold) > EPSILON);
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
Nested loops
• How can we print a table of values?
• Example 1, this table tells you the fate of $10,000 invested under various interest
rates for a different number of years.
Nested loops (Example 1)
• Here is the pseudocode:
• How do we print a table row? You need to program another loop.
int year;
for (year = YEAR_MIN; year <= YEAR_MAX; year = year + YEAR_INCR)
{
balance = future_value(initial_balance, rate, year);
cout << "\t" << balance;
}
• The loop printing a single row nested in the loop that traverses the interest rates.
Nested loops (Example 1)
• The loop printing a single row nested in the loop that traverses the interest rates.
Nested loops (Example 1)
• Here is the pseudocode:
• How do we print the table header? Another loop.
cout << "Rate ";
int year;
for (year = YEAR_MIN; year <= YEAR_MAX; year = year + YEAR_INCR)
{
cout << "\t" << year << " years";
}
Nested loops (Example 2)
• Sometimes the iteration count of the inner loop depends on the outer loop.
• Example 2: printing a triangle shape.
• To print n rows, use the loop:
• Each row contains i boxes.
for (int j = 1; j <= i; j++)
cout << "[]";
cout << "\n";
for (int i = 1; i <= n; i++)
• Putting the two loops together yields {
for (int j = 1; j <= i; j++)
cout << "[]";
cout << "\n";
}
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
Processing a Sequence of Inputs
• Whenever you read a sequence of input values, you need to have
some method of terminating the input.
• A number used to signal termination is called a sentinel.
• Sentinels only work if there is some restriction on the input.
• Common sentinel values are 0 or -1.
Processing a Sequence of Inputs (Example)
Processing a Sequence of Inputs
(Causing the Stream to Fail)
• When reading input from the console, you can close the stream manually.
• Ctrl + Z in Windows
• Ctrl + D in UNIX
• Reading from a closed stream causes the stream to enter the failed state.
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
Using Boolean Variables
• The bool type can hold exactly two values, denoted false and true.
• Example:
• Don’t:
Contents
• The if statement
• Loops
• The while loop
• The for loop
• The do loop
• Nested loops
• Processing a Sequence of Inputs
• Using Boolean Variables
• Processing Text Input
• Random numbers
Processing Text Input
• When processing text input, is the input structured as a sequence of
characters, words, or lines?
• (1) To input a sequence of word, use the loop
• (2) To process input one line at a time, use the getline function.
Processing Text Input
• (3) To process input character by character, use the loop
Contents
• The if statement
• Loops
• Random numbers
Random numbers
• rand()yields a random integer number between 0 and RAND_MAX
• pseudorandom numbers
• For random floating-point number
• rand() * 1.0 / RAND_MAX
• is a random floating-point value between 0 and 1
• a random integer x in a certain range, a <= x <= b
int a, b;
int x = a + rand() % (b - a + 1);
// rand() % (b - a + 1) to obtain a random value between 0 and b - a.