Title: Chapter 7 More Flow of Control
1Chapter 7More Flow of Control
Goals
- To analyze the use of Boolean expressions
- To introduce the notion of enumerated types
- To explore the switch statement as an
alternative to multiway if-else statements
- To view the conditional statement as a
alternative to a simple if-else statement
- To examine the for-statement as a looping option
- To demonstrate the design of good nested loops
2Precedence Rules for Boolean Expressions
With the addition of Boolean operators, the
precedence rules that C uses to evaluate
expressions become more complex.
- Parentheses still take the highest precedence
- Multiplication, division, and modulus come
second.
- Addition and subtraction take the next
precedence.
- Order-related inequality operators (lt, gt, lt,
gt) are next.
- The pure equality/inequality (, !) operators
are next.
- The Boolean AND operator () takes the next
precedence.
- The Boolean OR operator () takes the lowest
precedence.
- Precedence ties are still handled in
left-to-right fashion.
3Precedence Rules Examples
int x 7, y 7, z 7 if (x y z) cout
ltlt YES else cout ltlt NO
int a 5, b 4, c 3 if (a lt b lt c) cout
ltlt YES else cout ltlt NO
Output NO The left equality is checked and
evaluates to true (numerical 1), which is not
equal to the z-value!
Output YES The left inequality is checked and
evaluates to false (numerical 0), which is less
than the c-value!
4Boolean Expressions -Short-Circuit Evaluation of
When a Boolean expression using the operator
is evaluated, the first subexpression is
evaluated first. if it evaluates to false, then
the second subexpression is ignored.
When this code segment is encountered and xs
value is zero, z will be assigned either the
value 100 or the value -1.
if ((x ! 0) (y/x gt 1)) z 100 else z
-1
When this code segment is encountered and xs
value is zero, the program crashes due to the
attempt to divide by zero!
if ((y/x gt 1) (x ! 0)) z 100 else z
-1
5Boolean Expressions -Short-Circuit Evaluation of
When a Boolean expression using the operator
is evaluated, the first subexpression is
evaluated first. if it evaluates to true, then
the second subexpression is ignored.
When this code segment is encountered and cts
value is zero, the message is output.
if ((ct 0) (total/ct gt 70)) cout ltlt NO
PROBLEMO
When this code segment is encountered and cts
value is zero, the program crashes due to the
attempt to divide by zero!
if ((total/ct gt 70) (ct 0)) cout ltlt NO
PROBLEMO
6Enumerated Types
To enhance the readability of ones code, a
programmer can define an enumerated type, which
consists of a set of integer constants.
include ltiostream.hgt include ltfstream.hgt enum
MonthNumber JANUARY 1, FEBRUARY, MARCH,
APRIL, MAY, JUNE, JULY,
AUGUST, SEPTEMBER, OCTOBER, NOVEMBER,
DECEMBER double tabulateMonthlyGross(ifstream
grossFile, MonthNumber month) void
outputMonthlyGross(MonthNumber month, double
gross) void main() MonthNumber monthCount
JANUARY double monthlyGross, totalGross
0.0 ifstream fileContainingGrosses
fileContainingGrosses.open("GrossFile.txt")
cout.setf(iosfixed) cout.setf(iosshowpoint
) cout.precision(2) while (monthCount lt
DECEMBER) monthlyGross
tabulateMonthlyGross(fileContainingGrosses,
monthCount) outputMonthlyGross(monthCount,
monthlyGross) totalGross monthlyGross
monthCount MonthNumber(monthCount 1)
fileContainingGrosses.close() cout ltlt
endl ltlt endl ltlt "Total " ltlt totalGross ltlt endl
ltlt endl return
7double tabulateMonthlyGross(ifstream grossFile,
MonthNumber month) int monthLength int
day double dailyGross double gross
0.0 if (month FEBRUARY) monthLength
28 else if ((month APRIL) (month
JUNE) (month SEPTEMBER)
(month NOVEMBER)) monthLength 30
else monthLength 31 day 1
while (day lt monthLength) grossFile
gtgt dailyGross gross dailyGross
day return gross void
outputMonthlyGross(MonthNumber month, double
gross) cout ltlt "The gross for month "
ltlt month ltlt " is " ltlt gross ltlt endl
ltlt endl return
8switch Statements
C switch statements provide a simple
alternative to the use of convoluted nested
if-else statements.
if (month 2) if (year 4 0)
daysInMonth 29 else daysInMonth
28 else if ((month 4) (month
6) (month 9) (month
11)) daysInMonth 30 else daysInMonth
31
switch (month) case 2 if
(year 4 0) daysInMonth
29 else daysInMonth
28 break case 4
case 6 case 9 case 11 daysInMonth 30
break default daysInMonth 31 break
9Conditional Statements
C conditional statements provide a concise
alternative to the use of relatively simple
if-else statements.
if (value gt 0) cout ltlt GOOD else cout ltlt
BAD
(value gt 0) ? (cout ltlt GOOD) (cout ltlt BAD)
if (year 4 0) daysInMonth 29 else
daysInMonth 28
daysInMonth (year 4 0) ? 29 28
10include ltiostream.hgt int retrieveMovieType() cha
r retrieveMovieChoice(int type) void
outputClassicFilmsHeader() void
outputActionAdventureHeader() void
outputScienceFictionHeader() void
outputChildrensMoviesHeader() void
outputForeignFilmsHeader() void outputCharge(int
type, char choice) void main() char
movieChoice int movieType do
movieType retrieveMovieType()
movieChoice retrieveMovieChoice(movieType)
outputCharge(movieType, movieChoice)
while (movieType lt 0) return int
retrieveMovieType() int movieType cout
ltlt "Welcome to the Lackluster Video Channel!" ltlt
endl cout ltlt "Available ONLY at the Bates
Family Motel!" ltlt endl ltlt endl cout ltlt "Enter
the number corresponding to your desired movie
type." ltlt endl ltlt endl cout ltlt " 1 - Classic
Films" ltlt endl ltlt " 2 - Action/Adventure"
ltlt endl ltlt " 3 - Science Fiction" ltlt
endl ltlt " 4 - Children's Movies" ltlt endl
ltlt " 5 - Foreign Films" ltlt endl ltlt endl ltlt "
0 - Quit" ltlt endl ltlt endl ltlt "Enter
number here " cin gtgt movieType cout ltlt
endl return movieType
EXAMPLE
11The break statements ensure that the switch
statement is exited once the appropriate case is
handled. Without the break statements, multiple
functions might be called.
char retrieveMovieChoice(int type) char
movieChoice switch(type) case(1)
outputClassicFilmsHeader() break
case(2) outputActionAdventureHeader() break
case(3) outputScienceFictionHeader()
break case(4) outputChildrensMoviesHeade
r() break case(5) outputForeignFilmsHea
der() break switch(type)
case(1) case(2) case(3) case(4)
case(5) cout ltlt "\tEnter
letter here " cin gtgt
movieChoice break
default movieChoice 'Q' break
return movieChoice
When several cases warrant the same actions, the
code only needs to appear once, with no break
statements separating the cases.
The default case is executed if no other case
value matches. It doesnt need a break statement
at the end, but using one enhances readability
and modifiability.
12void outputClassicFilmsHeader() cout ltlt
"\tEnter the letter corresponding to the film you
wish to see." ltlt endl cout ltlt "\t A -
\"Dracula\"" ltlt endl ltlt "\t B -
\"Frankenstein\"" ltlt endl ltlt "\t C -
\"The Mummy\"" ltlt endl ltlt "\t D - \"The
Phantom Of The Opera\"" ltlt endl ltlt "\t E
- \"The Wolf-Man\"" ltlt endl ltlt endl ltlt
"\t Q - Quit" ltlt endl ltlt "\t R -
Return to Main Menu" ltlt endl ltlt endl
return void outputActionAdventureHeader()
cout ltlt "\tEnter the letter corresponding to the
film you wish to see." ltlt endl cout ltlt "\t A
- \"Death Wish\"" ltlt endl ltlt "\t B -
\"Die Hard\"" ltlt endl ltlt "\t C - \"Dirty
Harry\"" ltlt endl ltlt "\t D - \"Lethal
Weapon\"" ltlt endl ltlt "\t E - \"Rambo\""
ltlt endl ltlt endl ltlt "\t Q - Quit" ltlt endl
ltlt "\t R - Return to Main Menu" ltlt endl
ltlt endl return
13void outputScienceFictionHeader() cout ltlt
"\tEnter the letter corresponding to the film you
wish to see." ltlt endl cout ltlt "\t A -
\"Alien\"" ltlt endl ltlt "\t B -
\"Aliens\"" ltlt endl ltlt "\t C -
\"Predator\"" ltlt endl ltlt "\t D - \"The
Terminator\"" ltlt endl ltlt "\t E -
\"Terminator 2\"" ltlt endl ltlt endl ltlt "\t
Q - Quit" ltlt endl ltlt "\t R - Return to
Main Menu" ltlt endl ltlt endl return void
outputChildrensMoviesHeader() cout ltlt
"\tEnter the letter corresponding to the film you
wish to see." ltlt endl cout ltlt "\t A - \"The
Bad Seed\"" ltlt endl ltlt "\t B -
\"Children Of The Corn\"" ltlt endl ltlt "\t
C - \"The Exorcist\"" ltlt endl ltlt "\t D -
\"Lord Of The Flies\"" ltlt endl ltlt "\t E
- \"Rosemary\'s Baby\"" ltlt endl ltlt endl
ltlt "\t Q - Quit" ltlt endl ltlt "\t R -
Return to Main Menu" ltlt endl ltlt endl
return void outputForeignFilmsHeader()
cout ltlt "\tEnter the letter corresponding to the
film you wish to see." ltlt endl cout ltlt "\t A
- \"Cronos\"" ltlt endl ltlt "\t B -
\"Frenzy\"" ltlt endl ltlt "\t C - \"M\"" ltlt
endl ltlt "\t D - \"Nosferatu\"" ltlt endl
ltlt "\t E - \"The Quartermass Experiment\""
ltlt endl ltlt endl ltlt "\t Q - Quit" ltlt endl
ltlt "\t R - Return to Main Menu" ltlt endl
ltlt endl return
14Conditional statements enhance the readability of
the code when used to replace relatively short
if-else statements.
void outputCharge(int type, char choice)
switch(choice) case('A') case('a')
(type 4) ?
(cout ltlt "\tCharge 6.00")
(cout ltlt "\tCharge
3.50") break
case('C') case('c')
((type 3) (type
5)) ? (cout ltlt
"\tCharge 6.00")
(cout ltlt "\tCharge 3.50")
break
case('B') case('b') case('D') case('d')
case('E') case('e') cout ltlt "\tCharge
3.50" break case('R') case('r') type
-1 break default cout
ltlt "\tNo movie ordered. No charge.
if (type gt 0) cout ltlt endl ltlt endl ltlt
"Enjoy your stay at the Bates Motel!" cout ltlt
endl ltlt endl return
Any Boolean expression is permissible in a
conditional statement.
15SAMPLE EXECUTION SESSION
16The for Statement
The C for statement is designed to facilitate
looping when the control of the loop contains
three standard features
- An initialization action that is performed just
before the loop is started the first time.
- A Boolean expression that is checked just before
entering the loop at each iteration.
- An update action that is performed just after
each iteration of the loop is completed.
for (initAction booleanExp updateAction)
bodyOfLoop
17A for-loop Example
include ltiostream.hgt enum Day SUNDAY 1,
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,
SATURDAY const double PAY_RATE 5.15 double
retrieveHoursWorkedForDay(Day dayOfTheWeek) void
main() Day dayOfWeek double
hoursWorked double payForWeek 0.0 for
(dayOfWeek SUNDAY dayOfWeek lt SATURDAY
dayOfWeek Day(dayOfWeek 1))
hoursWorked retrieveHoursWorkedForDay(dayOfWeek)
(dayOfWeek SUNDAY) ?
(payForWeek 1.5 hoursWorked PAY_RATE)
(payForWeek hoursWorked PAY_RATE)
cout.setf(iosfixed)
cout.setf(iosshowpoint) cout.precision(2)
cout ltlt endl ltlt endl ltlt "Your Pay For The Week
Is " ltlt payForWeek ltlt endl ltlt endl
return
dayOfWeek is initialized to SUNDAY when the
for-loop is first encountered.
This inequality is checked just before the body
of the loop is entered (or re-entered).
This assignment statement is executed right after
each execution of the body of the loop.
18double retrieveHoursWorkedForDay(Day
dayOfTheWeek) double hours cout ltlt
"Enter the hours worked on " switch
(dayOfTheWeek) case SUNDAY cout ltlt
"Sunday " break case MONDAY cout ltlt
"Monday " break case TUESDAY cout ltlt
"Tuesday " break case WEDNESDAY cout ltlt
"Wednesday " break case THURSDAY cout ltlt
"Thursday " break case FRIDAY cout ltlt
"Friday " break case SATURDAY cout ltlt
"Saturday " break cin gtgt hours
return hours
19Another for-loop Example
include ltiostream.hgt void main() char
party int leapYear int elephants 0
int donkeys 0 for (leapYear 1996
leapYear gt 1920 leapYear - 4) cout
ltlt "Which party won in " ltlt leapYear
ltlt "? (Enter R or D) " cin gtgt party
(party 'R') ? elephants donkeys
(elephants gt donkeys) ? (cout ltlt
"\nRepublicans Rule!\n\n") ((donkeys gt
elephants) ? (cout ltlt "\nDemocrats
Dominate!\n\n") (cout ltlt
"\nTiebreaker Time!\n\n")) return
20Nested for-loops
include ltiostream.hgt void main() int
iterationNbr, repetitionNbr, indentSpaceNbr
for (iterationNbr 1 iterationNbr lt 25
iterationNbr) for (repetitionNbr 1
repetitionNbr lt 1000 repetitionNbr)
cout ltlt '\r' for (indentSpaceNbr
1 indentSpaceNbr lt iterationNbr
indentSpaceNbr) cout ltlt ' '
cout ltlt "HAPPY NEW YEAR!" cout ltlt
endl ltlt endl return
21include ltiostream.hgt include ltiomanip.hgt int
retrieveMonth() int retrieveYear() int
calculateNbrDaysInMonth(int mo, int yr) void
outputHeader(int mo, int yr) void
outputCalendar(int daysInMonth, int
firstDay) void main() int year int
month int nbrDaysInMonth int
firstDayOfYear int firstDayOfMonth int
i month retrieveMonth() year
retrieveYear() firstDayOfYear (((year
3)/4) year 5) 7 1 firstDayOfMonth
firstDayOfYear for (i 1 i lt month i)
nbrDaysInMonth calculateNbrDaysInMonth(
i,year) firstDayOfMonth (i lt month) ?
(firstDayOfMonth nbrDaysInMonth)
((firstDayOfMonth - 1) 7 1)
outputHeader(month, year) outputCalendar(nbrDa
ysInMonth, firstDayOfMonth) return
A More Elaborate for-loop Example
22int retrieveMonth() int m cout ltlt "Enter
the month of the calendar to be generated "
cin gtgt m for ( ((m lt 0) (m gt 12)) )
cout ltlt "\nYou must enter a number
between 1 and 12 for the month.\n" ltlt
"Enter the month of the calendar to be generated
" cin gtgt m return m int
retrieveYear() int y cout ltlt "\nEnter
the year of the calendar to be generated "
cin gtgt y for ( ((y lt 1900) (y gt 2100))
) cout ltlt "\nThis program only works
for the 20th and 21st centuries!.\n\n"
ltlt "Enter the year of the calendar to be
generated " cin gtgt y return y
Notice that these for loops perform no
initialization actions and no update actions!
23int calculateNbrDaysInMonth(int mo, int yr)
int days switch (mo) case (2)
days (yr 4 0) ? (29) (28) break
case (4) case (6) case (9)
case (11) days 30 break default
days 31 break return
days void outputHeader(int mo, int yr)
cout ltlt "\n\n MONTH " ltlt mo ltlt " OF THE YEAR "
ltlt yr ltlt endl ltlt endl cout ltlt setw(4) ltlt 'S'
ltlt setw(4) ltlt 'M' ltlt setw(4) ltlt 'T' ltlt setw(4) ltlt
'W' ltlt setw(4) ltlt 'T' ltlt setw(4) ltlt 'F'
ltlt setw(4) ltlt 'S' ltlt endl return
24void outputCalendar(int daysInMonth, int
firstDay) int nbrRows ((daysInMonth
firstDay - 1) gt 28) ? (5) (4) int day 1
int row int column int nbrColumns
7 for (row 1 row lt nbrRows row)
for (column 1 column lt nbrColumns
column) if (((row 1)
(column lt firstDay)) ((row
nbrRows) (day gt daysInMonth)))
cout ltlt setw(4) ltlt ' ' else
cout ltlt setw(4) ltlt day
day cout ltlt endl
cout ltlt endl ltlt endl return