11
Chapter 7: Advanced Control FlowChapter 7: Advanced Control Flow Chapter GoalsChapter Goals
• To recognize the correct ordering of decisions To recognize the correct ordering of decisions in multiple branches in multiple branches
• To program conditions using Boolean To program conditions using Boolean operators and variables operators and variables
• To understand nested branches and loops To understand nested branches and loops • To be able to program loops with the for and To be able to program loops with the for and
do/while statements do/while statements • To learn how to process character, word, and To learn how to process character, word, and
line input line input • To learn how to read input from a file through To learn how to read input from a file through
redirection redirection • To implement approximations and To implement approximations and
simulations simulations
22
Multiple AlternativesMultiple Alternatives By using collections of if/else statements, a By using collections of if/else statements, a
program can distinguish between multiple program can distinguish between multiple alternatives. alternatives.
Example:Example: The user enters the name of a coin, and The user enters the name of a coin, and the program returns the value. the program returns the value.
This program has five alternatives to choose from: This program has five alternatives to choose from: • "penny" "penny" • "nickel" "nickel" • "dime" "dime" • "quarter" "quarter" • erroneous input erroneous input
The order that the alternatives are checked is The order that the alternatives are checked is unimportant unimportant
33
Multiple Alternatives Multiple Alternatives (Coins Flowchart)(Coins Flowchart)
44
Multiple Alternatives (coins6.cpp) Multiple Alternatives (coins6.cpp) 01: 01: #include#include <iostream> <iostream> 02: 02: 03: 03: #include#include <string> <string> 04: 04: 05: 05: usingusing namespacenamespace std; std; 06: 06: 07: int 07: int mainmain() {() { 09: cout << "Enter coin name: "; 09: cout << "Enter coin name: "; 10: string name; 10: string name; 11: cin >> name; 11: cin >> name; 12: double value = 0; 12: double value = 0; 13: 13: 14: 14: ifif (name == "penny") (name == "penny") 15: value = 0.01; 15: value = 0.01; 16: 16: elseelse ifif (name == "nickel") (name == "nickel") 17: value = 0.05; 17: value = 0.05; 18: 18: elseelse ifif (name == "dime") (name == "dime") 19: value = 0.10; 19: value = 0.10; 20: 20: elseelse ifif (name == "quarter") (name == "quarter") 21: value = 0.25; 21: value = 0.25; 22: 22: elseelse 23: cout << name << " is not a valid coin name\n"; 23: cout << name << " is not a valid coin name\n"; 24: cout << "Value = " << value << "\n"; 24: cout << "Value = " << value << "\n"; 25: 25: 26: 26: returnreturn 0; 0; 27: } 27: }
55
Multiple AlternativesMultiple Alternatives
In some cases, the order of the tests is In some cases, the order of the tests is important.important.
ExampleExample: A program that displays a : A program that displays a description of the likely impact of an description of the likely impact of an earthquake based on its magnitude on the earthquake based on its magnitude on the Richter scale.Richter scale.• Note that the order of the tests ensures that Note that the order of the tests ensures that
the right results are printed (see following the right results are printed (see following code). code).
• Note that the if/else/else structure ensures the Note that the if/else/else structure ensures the alternatives are exclusive. Independent if alternatives are exclusive. Independent if statements may cause a single input to print statements may cause a single input to print several messages. several messages.
66
Multiple Alternatives (richter.cpp) Multiple Alternatives (richter.cpp) #include#include <iostream> <iostream> #include#include <string> <string> usingusing namespacenamespace std; std; int int mainmain() { () { cout << "Enter a magnitude on the Richter scale: "; cout << "Enter a magnitude on the Richter scale: "; double richter; double richter; cin >> richter; cin >> richter; ifif (richter >= 8.0) (richter >= 8.0) cout << "Most structures fall\n"; cout << "Most structures fall\n"; elseelse ifif (richter >= 7.0) (richter >= 7.0) cout << "Many buildings destroyed\n"; cout << "Many buildings destroyed\n"; elseelse ifif (richter >= 6.0) (richter >= 6.0) cout << "Many buildings considerably damaged, " cout << "Many buildings considerably damaged, " << "some collapse\n"; << "some collapse\n"; elseelse ifif (richter >= 4.5) (richter >= 4.5) cout << "Damage to poorly constructed buildings\n"; cout << "Damage to poorly constructed buildings\n"; elseelse ifif (richter >= 3.5) (richter >= 3.5) cout << "Felt by many people, no destruction\n"; cout << "Felt by many people, no destruction\n"; elseelse ifif (richter >= 0) (richter >= 0) cout << "Generally not felt by people\n"; cout << "Generally not felt by people\n"; elseelse cout << "Negative numbers are not valid\n"; cout << "Negative numbers are not valid\n"; returnreturn 0; 0; } }
77
Nested BranchesNested Branches The two-level decision process is reflected in two levels of if The two-level decision process is reflected in two levels of if
statements. statements. We say the income test is We say the income test is nestednested inside the test for filing status. inside the test for filing status.
• More complicated decisions may require deeper levels of nesting.
88
Nested Branches (tax.cpp) Nested Branches (tax.cpp) ExampleExample: :
ifif (marital_status == "s“) { (marital_status == "s“) { ifif (income <= SINGLE_LEVEL1) (income <= SINGLE_LEVEL1) tax = RATE1 * income; tax = RATE1 * income; elseelse ifif (income <= SINGLE_LEVEL2) (income <= SINGLE_LEVEL2) tax = SINGLE_TAX1 tax = SINGLE_TAX1 + RATE2 * (income - SINGLE_LEVEL1); + RATE2 * (income - SINGLE_LEVEL1); elseelse tax = SINGLE_TAX2 tax = SINGLE_TAX2 + RATE3 * (income - SINGLE_LEVEL2); + RATE3 * (income - SINGLE_LEVEL2); } } else else { { ifif (income <= MARRIED_LEVEL1) (income <= MARRIED_LEVEL1) tax = RATE1 * income; tax = RATE1 * income; elseelse ifif (income <= MARRIED_LEVEL2) (income <= MARRIED_LEVEL2) tax = MARRIED_TAX1 tax = MARRIED_TAX1 + RATE2 * (income - MARRIED_LEVEL1); + RATE2 * (income - MARRIED_LEVEL1); elseelse tax = MARRIED_TAX2 tax = MARRIED_TAX2 + RATE3 * (income - MARRIED_LEVEL2); + RATE3 * (income - MARRIED_LEVEL2); } }
cout << "The tax is $" << tax << "\n"; cout << "The tax is $" << tax << "\n";
99
Boolean Operations Boolean Operations An operator that combines test conditions is An operator that combines test conditions is
called a called a logicallogical operator operator. .
The && (The && (andand) operator combines several tests ) operator combines several tests into a new test that passes only when into a new test that passes only when all the all the conditions are trueconditions are true. .
ExampleExample: : if (now.get_hours()==homework.get_hours() if (now.get_hours()==homework.get_hours()
&& now.get_minutes() == homework.get_minutes()) && now.get_minutes() == homework.get_minutes())
cout << "The homework is due right now!\n";cout << "The homework is due right now!\n";
The || (The || (oror) operator combines two or more ) operator combines two or more conditions and succeeds if conditions and succeeds if at least one of the at least one of the conditions is trueconditions is true. .
ExampleExample: : if (state == "HI" || state == "AK") if (state == "HI" || state == "AK")
shipping_charge = 10.00; shipping_charge = 10.00;
1010
Summary of Boolean OperationsSummary of Boolean Operations
aa bb a && ba && b
truetrue truetrue truetrue
truetrue falsefalse falsefalse
falsefalse truetrue falsefalse
falsefalse falsefalse falsefalse
aa bb a || ba || b
truetrue truetrue truetrue
truetrue falsefalse truetrue
falsefalse truetrue truetrue
falsefalse falsefalse falsefalse
aa !a!a
truetrue falsefalse
falsefalse truetrue
1111
Examples of boolean ExpressionsExamples of boolean Expressions
The value of x is in interval [3, 10]The value of x is in interval [3, 10]
(x >= 3 && x <= 10)(x >= 3 && x <= 10)
The value of x is outside the interval The value of x is outside the interval [3, 10][3, 10]
(x < 3 || x > 10)(x < 3 || x > 10)
An alternative for previous is: An alternative for previous is:
!(x >= 3 && x <= 10)!(x >= 3 && x <= 10)
1212
DeMorgan's LawDeMorgan's Law DeMorgan's Law has two forms: DeMorgan's Law has two forms:
• !(A && B)!(A && B) is the same as is the same as !A || !B!A || !B• !(A || B)!(A || B) is the same as is the same as !A && !B!A && !B
Pay particular attention to the fact that the Pay particular attention to the fact that the && and || operators are reversed by && and || operators are reversed by moving the not inwards. moving the not inwards.
ExampleExample: : state != "AK" && state != "HI"state != "AK" && state != "HI"
is the same as is the same as !(state == "AK") && !(state == "HI")!(state == "AK") && !(state == "HI")
which is the same as which is the same as !(state == "AK" || state == "HI") !(state == "AK" || state == "HI")
1313
The for LoopThe for Loop The most common loop has the form The most common loop has the form
i = start;while (i <= end) { . . . i++; }
• Because this loop is so common, there is a special form for it.
for (i = start; i <= end; i++) { …}
1414
The for Loop (cont.)The for Loop (cont.)
ExampleExample
int product = 1; int product = 1;
for (int i = 1; i <= n; i++) for (int i = 1; i <= n; i++) product = product = product * i; product * i;
1515
The for Loop Syntax The for Loop Syntax General syntax of for loopGeneral syntax of for loop
for (for (init_expressioninit_expression;; condition condition;; update_expression update_expression)) statementstatement (loop body) (loop body)
ExampleExample: :
for (int i = 1; i <= 10; i++) for (int i = 1; i <= 10; i++) sum = sum + i; sum = sum + i;
PurposePurpose: :
Execute the initialization statement. Execute the initialization statement. While the condition remains true, While the condition remains true, execute the statement and update the execute the statement and update the expression.expression.
1616
Example of for loop (n!)Example of for loop (n!)
#include#include <iostream> <iostream>
usingusing namespacenamespace std; std;
int int mainmain() { () {
cout << "Please enter a number: "; cout << "Please enter a number: ";
int n; int n;
cin >> n; cin >> n;
int product = 1; int product = 1;
forfor (int i = 1; i <= n; i++) { (int i = 1; i <= n; i++) {
product = product * i; product = product * i;
} }
cout << n << "! = " << product << "\n"; cout << n << "! = " << product << "\n";
returnreturn 0; 0;
} }
1717
The do LoopThe do Loop Sometimes you want to execute the body of a Sometimes you want to execute the body of a
loop at least once and perform the loop test after loop at least once and perform the loop test after the body was executed. the body was executed.
The do/while loop serves that purpose. The do/while loop serves that purpose. General format or syntax is: General format or syntax is:
do { do { statementsstatements … … loop bodyloop body } while (} while (conditioncondition); );
ExampleExample: : do { do { xold = xnew; xold = xnew; xnew = (xold + a / xold) / 2; xnew = (xold + a / xold) / 2; } while (fabs(xnew - xold) > } while (fabs(xnew - xold) >
EPSILON); EPSILON);
1818
Flowchart for do loopFlowchart for do loop
do { do {
xold = xnew; xold = xnew;
xnew = (xold + a / xold) / 2; xnew = (xold + a / xold) / 2;
} while (fabs(xnew - xold)>EPSILON); } while (fabs(xnew - xold)>EPSILON);
PurposePurpose: :
1.1. Execute the statement inside the Execute the statement inside the loop (loop body).loop (loop body).
2.2. Then test the condition. Then test the condition.
3.3. If the condition is true, repeat the If the condition is true, repeat the previous two steps. previous two steps.
1919
Example of Example of dodo Loop Loop // Computes an approximate value of the square root// Computes an approximate value of the square root // of a number given as input.// of a number given as input.
#include#include <iostream> <iostream> #include#include <cmath> <cmath> usingusing namespacenamespace std; std; int int mainmain() { () { cout << "Please enter a number: "; cout << "Please enter a number: "; double a; double a; cin >> a; cin >> a; constconst double EPSILON = 1E-14; double EPSILON = 1E-14; double xnew = a; double xnew = a; double xold; double xold; do do { { xold = xnew; xold = xnew; xnew = (xold + a / xold) / 2; xnew = (xold + a / xold) / 2; } } whilewhile ( (fabsfabs(xnew - xold) > EPSILON);(xnew - xold) > EPSILON); cout << "The square root is " << xnew << "\n"; cout << "The square root is " << xnew << "\n"; returnreturn 0; 0; } }
2020
Nested LoopsNested Loops How can we print a table of values? How can we print a table of values?
For example, this table tells you the fate of $10,000 invested For example, this table tells you the fate of $10,000 invested under various interest rates for a different number of years. under various interest rates for a different number of years.
2121
Nested Loops (cont)Nested Loops (cont) Here is the pseudocode: Here is the pseudocode:
print table headerprint table headerdouble rate;double rate;for (rate = RATE_MIN; rate <= RATE_MAX; for (rate = RATE_MIN; rate <= RATE_MAX; rate = rate + RATE_INCR) { rate = rate + RATE_INCR) { print table rowprint table row} }
How do we print a table row? You need to How do we print a table row? You need to program another loop. program another loop. int year;int year;for (year = YEAR_MIN; year <= YEAR_MAX;for (year = YEAR_MIN; year <= YEAR_MAX; year = year + YEAR_INCR) { year = year + YEAR_INCR) {
balance = future_value(initial_balance, rate, balance = future_value(initial_balance, rate,
year);year); cout << setw(10) << balance;cout << setw(10) << balance;} }
2222
Nested Loops (cont)Nested Loops (cont) It's a good idea to print the table header as a It's a good idea to print the table header as a
loop as well. loop as well.
cout << "Rate ";cout << "Rate ";int year;int year;for (year = YEAR_MIN; year <= YEAR_MAX;for (year = YEAR_MIN; year <= YEAR_MAX; year = year + YEAR_INCR) { year = year + YEAR_INCR) { cout << setw(2) << year cout << setw(2) << year
<< " years";<< " years";} }
Once everything is put together, you have the Once everything is put together, you have the loop printing a single row loop printing a single row nestednested in the loop in the loop that traverses the interest rates. that traverses the interest rates.
2323
Part of the Program…Part of the Program… ……
/* print table header *//* print table header */ cout << " Rate "; cout << " Rate "; int year; int year; forfor (year = YEAR_MIN; year <= YEAR_MAX; (year = YEAR_MIN; year <= YEAR_MAX; year = year + YEAR_INCR) { year = year + YEAR_INCR) { cout << cout << setwsetw(2) << year << " years ";(2) << year << " years "; } } cout << "\n"; cout << "\n"; cout << fixed << cout << fixed << setprecisionsetprecision(2);(2); double rate; double rate; double initial_balance = 10000; double initial_balance = 10000; forfor (rate = RATE_MIN; rate <= RATE_MAX; (rate = RATE_MIN; rate <= RATE_MAX; rate = rate + RATE_INCR) { rate = rate + RATE_INCR) { /* print table row *//* print table row */ int year; int year; cout << cout << setwsetw(5) << rate;(5) << rate; forfor (year = YEAR_MIN; year <= YEAR_MAX; (year = YEAR_MIN; year <= YEAR_MAX; year = year + YEAR_INCR) { year = year + YEAR_INCR) { double balance = double balance = initial_balance * initial_balance * powpow(1 + rate / 100, year);(1 + rate / 100, year); cout << cout << setwsetw(10) << balance;(10) << balance; } } cout << "\n"; cout << "\n"; } }