More Control Structures forever if do-while

advertisement
More Control Structures
if and switch
(Chap. 8)
do-while and forever loops
(Chap. 9)
1
Are there any Weaknesses
in the if Statement?
For some problems, the "waterfall" execution of
the multi-branch if leads to poor (or perhaps
unacceptable) performance of a program.
Example: Suppose we need a function that,
given the number of a day of the week (1-7),
computes its corresponding name (SundaySaturday)?
2
Algorithm:
0. Receive dayNumber.
1. If dayNumber == 1:
Return "Sunday".
Else if dayNumber == 2:
Return "Monday".
Else if dayNumber == 3:
Return "Tuesday".
Else if dayNumber == 4:
Return "Wednesday".
Else if dayNumber == 5:
Return "Thursday".
Else if dayNumber == 6:
Return "Friday".
Else if dayNumber == 7:
Return "Saturday".
Else
Display an error message, and return "".
3
// Receive a day number, return its name
string dayName(int dayNumber)
{
if (dayNumber == 1)
return "Sunday";
else if (dayNumber == 2)
return "Monday";
else if (dayNumber == 3)
return "Tuesday";
else if (dayNumber == 4)
return "Wednesday";
else if (dayNumber == 5)
return "Thursday";
else if (dayNumber == 6)
return "Friday";
else if (dayNumber == 7)
return "Saturday";
else
{
cerr << "\n** DayName: invalid day number\n";
return "";
}
}
4
The multi-branch if has non-uniform execution
time:
1 comparison
• Computing "Sunday" requires __
2 comparisons
• Computing "Monday" requires __
• ...
7 comparisons
• Computing "Saturday" requires __
Computations that are "later" in the if take longer.
There are situations where the time to select one of
many statements must be uniform.
5
A Solution
The C++ switch statement provides an alternative:
string dayName(int dayNumber)
{
switch (dayNumber)
{
case 1:
return "Sunday";
case 2:
return "Monday";
case 3:
Cases need not
return "Tuesday";
be in order nor
case 4:
consecutive, and
return "Wednesday";
there can be
case 5:
multiple labels.
return "Thursday";
case 6:
return "Friday";
case 7:
return "Saturday";
default:
cerr << "\n* dayName: invalid day number\n";
return "";
}
10
}
The switch Statement
The switch statement provides multi-branch selection,
but guarantees uniform execution time,
regardless of which branch is selected.
Thus, the time to select
return "Saturday";
is identical to the time to select
return "Sunday";
if a switch statement is used to select them.
7
Pattern:
switch (expression)
{
caseList1
StatementList1
caseList2
StatementList2
...
caseListN
StatementListN
default:
StatementListN+1
}
Enclose in { } if
it contains any
declarations
where expression is an integer-compatible expression,
each caseList is one or more cases of this form:
case ConstantValue :
and each StatementList usually ends with a break or
return statement.
8
Warning
C++ switch statements exhibit drop-through behavior.
1. expression is evaluated.
2. If expression == constanti , control jumps to
the statement associated with constanti .
3. Control continues within the switch statement
until:
a. The end of the switch is reached;
b. A break is executed, terminating the switch;
c. A return is executed, terminating the function; or
d. An exit() is executed, terminating the program.
9
Example
What will the following statement display,
if the value of dayNumber is 6?
switch(dayNumber)
{
case 1:
cout << "Sunday";
case 2:
cout << "Monday";
case 3:
cout << "Tuesday";
case 4:
cout << "Wednesday";
case 5:
cout << "Thursday";
case 6:
cout << "Friday";
case 7:
cout << "Saturday";
default:
cout << "Error!" << endl;
}
Friday SaturdayError!
Output: __________________
10
Solution
To avoid the "dropthrough" behavior, we
need to add a break
or return statement
at the end of each case:
switch(dayNumber)
{
case 1:
cout << "Sunday";
break;
case 2:
cout << "Monday";
break;
case 3:
cout << "Tuesday";
break;
case 4:
cout << "Wednesday";
break;
case 5:
cout << "Thursday";
break;
case 6:
cout << "Friday";
break;
case 7:
cout << "Saturday";
break;
default:
cout << "Error!" << endl;
}
Friday
Output when dayNumber is 6? _______________
11
Other Repetition Structures
The most common use of for
loops is to count from one
value first to another value last:
for (int count = first;
count <= last;
count++)
Statement
count = first
F
count <= last
T
Statement
Or to count down from a
larger value to a smaller one:
for (int count = first;
count >= last;
count--)
Statement
count++
12
More General Loops
But sometimes — e.g., when
reading data — we need a more
general repetition structure 
one in which we don't know in
advance how many iterations
will be needed.
For example, in the structure
pictured at the right, repetition
continues so long as some
Condition is true.
StatementList1
F
Condition
T
StatementList2
13
The while Loop
For such situations, C++
provides the while loop:
while (Condition)
Statement
Statement is almost
F
Condition
T
Statement
always a compound
C++ statement.
Repetition continues while
the Condition is true.
14
Post-test Loops
If StatementList2 is
omitted in our general
repetition structure, we
get a test-at-the-bottom
or post-test loop:
StatementList1
F
Condition
T
15
The do Loop
For such situations, C++
provides the do loop:
NOTE!
do
Statement
while (Condition);
Statement is almost always a
compound C++ statement.
Statement
F
T
Condition
Repetition "does" Statement
while Condition is true.
16
The do-loop is good for query-controlled input loops:
do
{
cout << "\nEnter a failure time: ";
cin >> failureTime;
failureTimeSum += failureTime;
numComponents++;
cout << "Do you have more data to enter (y or n)? ";
cin >> response;
}
while (response == 'y' || response == 'Y');
The do-loop is good for fool-proofing input loops:
do
{
Prompt for a menu selection and have the user enter it
}
while ( not a valid menu selection );
17
Test-in-the-Middle Loops
More general loops like that
pictured earlier in which the
termination test is made neither at
the top nor the bottom of the loop
are sometimes called
test-in-the-middle loops.
Note: The"T" and "F" labels on
Condition have been switched here
so that repetition terminates when
Condition becomes true.
StatementList1
T
Condition
F
StatementList2
This makes it easier to implement
this structure.
18
Forever Loops
Such test-in-the-middle loops
can be implemented in C++
with a for-loop of the form:
for (;;) // or while (true)
{
StatementList1
if (Condition) break;
StatementList2
}
StatementList1
T
Condition
F
StatementList2
Because the for clause contains
no expressions to control repetition
(thus allowing an infinite loop), this is
sometimes called a forever loop.
19
Test-in-the-Middle Input Loops
The forever loop is very useful for constructing
sentinel-controlled input loops:
Good to
set off
termination
test with
blank line
before and
after it.
for (;;)
// or
{
Input dataValue
while (true)
if (dataValue == sentinel) break;
}
Process dataValue
Note that when the sentinel value is input, it
does not get processed as a "regular" data value.
Also note that if the sentinel value is the first value
entered, repetition terminates immediately.
20
An Example
// Read, count, find mean of a list of numbers
int count = 0;
double value,
sum = 0,
mean;
for (;;)
{
cout << "Enter next value (-999 to stop): ";
cin >> value;
if (value == -999) break;
}
count++;
sum += value;
if (count == 0)
cerr << "No values entered\n";
else
mean = sum / count;
21
Summary
C++ provides four repetition statements:
• The for loop, for counting.
• The while loop, a general-purpose pretest
loop.
• The do loop, a general-purpose post-test loop.
• The forever loop, a general-purpose test-inthe-middle loop.
22
The four C++ loops provide very different behaviors:
• The for loop is a loop designed for counting that
provides pretest behavior.
• The while loop is a general-purpose loop that
provides test-at-the-top (pretest) behavior.
• The do loop is a general-purpose loop that provides
test-at-the-bottom (post-test) behavior.
• The forever loop is a general-purpose loop that
provides test-in-the-middle behavior.
23
Choosing a Loop:
• Use the for loop for problems that require counting over
some range of values.
• For other problems, identify the condition needed to
terminate repetition and then determine whether
execution needs to:
use a:
skip the loop body if termination
condition doesn't hold
while loop
go through the body at least
once before checking termination
condition
do loop
go through the first part of loop
body before checking termination
condition and skip second part
if it holds
forever loop
24
Download