Control Structures
Controlling the flow of a program is a very important aspect of programming.
There may be many different ways to find the solution to a particular problem,
but you will want to look for the best and fastest way. C++ has four types
of control structures: sequential, selection (decision), repetition (loops),
and subprograms (functions). These structures simply control the execution
of a program.
Sequential
Sequential means the program flow moves from one statement to the next, that
statement moves to the next, and so on. It is the simplest form of structures,
and it is not likely to use sequential structuring when developing complex
programs.
Selection (decision)
Selection structures make decisions and perform commands according to the desicion
making. Selection structures involve "if statments" which are statements like "if
this, then do that" and "if not this, then do that". With "if statements",
we can also include "nested if statements", which are "if statements" inside
other "if statements". Another form of selection structures is called a "switch
statement", which is very powerful for certain situations but not others. "Switch
statements" focus on the value of a particular variable and perform different "cases" accordingly.
Repetition
Repetition structures are used when something needs to be repeated a certain
number of times through the use of "loops". A loop is simply a statement that
completes iterations or cycles until a certain value is reached and then execution
moves to the next executable statement. For instance, if you were to ask the
user to enter ten values to find the average of the numbers, you could write
a loop that would continue letting the user enter numbers until ten numbers
had been entered.
Subprograms (functions)
A function is a subprogram that performs a specific task and may return a value
to the statement that called or invoked it. Functions make programming very
powerful because once you develop a function to handle a particular situation,
you can use that function for other programs. A function can call another function,
which may call another function, and so on. It is a great way to organize your
program and break your program down into logical steps.
After a very brief intro to the different types of control structures, it's
time to move on and find out how you can use each type. We will skip over sequential
structures since they are pretty much self-explanatory and elementary and move
on to selection statements. Read on for more about selection structures and "if
statements"...
Selection Statements
When dealing with selection statments, there are generally three versions:
one-way, two-way, and multi-way. One-way decision statements do some particular
thing or they don't. Two-way decision statements do one thing or do another.
Multi-way decision statements can do many different things depending on the
value of an expression.
One-Way Decisions
One-way decisions are handled with an "if statement" and either do some particular
thing or do nothing at all. The decision is based on a logical expression which
either evaluates to true or false. If the logical expression is evaluated to
true, then the corresponding statement is executed; if the logical expression
evaluates to false, control goes to the next executable statement. The form
of a one-way decision statement is as follows:
if ( logical expression )
stmtT;
The stmtT can be a simple or compound statement. Simple involves 1 single statement.
Compound involves 1 or more statements enclosed with curly braces { }. A compound
statement is called a block statement.
Example 1: simple statement
int c = 3;
.
.
.
if ( c > 0 )
cout << "c = " << c << endl;
Example 2: compound statement
int c = 10;
.
.
.
if ( c > 5 )
{
b = 2 * b + c;
cout << c * c * b << endl;
}
Two-Way Decisions
Two-way decisions are handled with "if / else statements" and either do one
particular thing or do another. Similar to one-way decisions, the decision
is based on a logical expression. If the expression is true, stmtT will be
executed; if the expression is false, stmtF will be executed. The form of a
two-way decision is as follows:
if ( logical expresion )
stmtT;
else
stmtF;
stmtT and stmtF can be simple or compound statements. Remember that compound
statments are always enclosed with curly braces { }.
Example 1:
int c = 10;
.
.
.
if ( c > 0 )
cout << "c is a positive integer" << endl;
else
cout << "c is a negative integer" << endl;
Example 2:
int num;
.
.
[num gets a value]
.
.
if ( num % 2 == 0 )
cout << "num is an even integer" << endl;
else
cout << "num is an odd integer" << endl;
Practical use example:
Suppose you are to write code that will calculate the earnings by workers who
are paid an hourly wage, with weekly hours greater than 40 being paid "time
and a half". Suppose weekly hours and hourly rate are known in the program.
Two options of code to handle this situation are as follows:
Option 1 using simple statements:
if ( weeklyHours <= 40 )
earnings = hourlyRate * weeklyHours;
else
earnings = 40 * hourlyRate + ( weeklyHours
- 40 ) * hourlyRate * 1.5;
Option 2 using a simple and compound statement:
if ( weeklyHours <= 40 )
earnings = hourlyRate * weeklyHours;
else
{
offHours = weeklyHours - 40;
regpay = 40 * hourlyRate;
earnings = regpay + offHours * hourlyRate
* 1.5;
}
Multi-Way Decisions
Multi-way decision statements involve using "if / else if" statements, "nested
ifs", or "switch" statments. They are all used to evaluate a logical expression
that could have several possible values. "if / else if" statements are often
used to choose between ranges of values. Switch statements are discussed in
next section [see Switch Statements].
The form of a mult-way decision using "if / else if" statments is as follows:
if ( logical expression )
stmtT1;
else if ( logical expression )
stmtT2;
else if ( logcial expression )
stmtT3;
.
.
.
else if ( logical expression )
stmtTN;
else
stmtF;
If the first logical expression is evaluated to true, then stmtT1 is executed.
If the second logical expression is true, then stmtT2 is executed and so on
down the line. If none of the logical expressions are true, then the statement
after "else" is executed which is stmtF.
The form of a multi-way decision using "nested ifs" is as follows:
if ( conditionA )
{
if ( conditionB )
stmtBT;
else
stmtBF;
}
else
stmtAF;
If conditionA is evaluated to true, then execution moves into the nested if
and evaluates conditionB. If conditionA is evaluated to false, then stmtAF
is executed.
Example 1:
int x;
if ( x > 0 )
cout << "x is positive" << endl;
else if ( x = 0 )
cout << "x is zero" << endl;
else
cout << "x is negative" << endl;
Example 2:
char ch;
if ( ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z'
)
cout << "ch contains a letter" << endl;
else if ( ch >= '0' && ch <= '9' )
cout << "ch represents a digit" << endl;
else if ( ch == ' ' || ch == '\t' || ch == '\n' )
cout << "ch is white space" << endl;
else
cout << "ch is a misc. character" << endl;
Example 3:
int score;
.
.
[score gets a value]
.
.
if ( score >= 90 )
grade = 'A';
else if ( score >= 80 )
grade = 'B';
else if ( score >= 70 )
grade = 'C';
else if ( score >= 60 )
grade = 'D';
else
grade = 'F';
Example 4:
if ( x > 25 )
if ( x < 50 )
cout << "x
is a mid-range value" << endl;
else
cout << "x
is a high value" << endl;
stmt-list-2;
break;
case label - 3 :
stmt-list-3;
break;
.
.
.
case label - n :
stmt-list-n;
break;
default :
stmt-list;
}
During execution, the expression is evaluated. If the value of the expression
matches label - 1, then stmt-list-1 (and perhaps all lists below) will be executed.
If not, execution will move on to check label - 2 and so on. If no labels match
the expression, default will be executed. Inside each case and at the end of
every statment list (except default) there must be a break statement, which
terminates the innermost enclosing switch or loop statement (not recommended
with loops ).
Here are some final notes about switch statements: the expression being tested
must result in an integral value (int or single char), case labels must be
integral constants (either literals or named constants), each label within
a switch should be unique, and each stmt-list may contain 0 or more stmts which
do not need to enclosed with curly braces { }.
Example:
Suppose a variable named score is an int variable that contains the number
of points scored on a football play. Consider the following code:
switch ( score )
{
case 1 : cout << "Extra Point" << endl;
break;
case 2 : cout << "Safety of two
point conversion" << endl;
break;
case 3 : cout << "Field Goal" << endl;
break;
case 6 : cout << "Touchdown" << endl;
break;
default : cout << "Invalid score
on a football play." << endl;
}
With selection statements out of the way, it's time to talk about iteration
(or looping) in a program. This, of course, involves using loop statements.
Read on to explore the world of looping...
While Loops
A loop is a statement of code that does something over and over again until
the logical expression of the loop evaluates to false. It is simply a way of
repeating code over and over again until some particular value is reached.
It can also be an effective way of making sure the user is inputting the correct
type of input (data validation). A loop is different from an if statement in
that if the logical expression is true, the stmt will be executed and control
will go back to check the logical expression again, ..., and again, until eventually
the logical expression becomes false. One thing to avoid is writing code that
produces an infinite loop, which is a loop that never stops until you press
ctrl-break on your keyboard. In order to avoid infinite loops, you need a statement(s)
inside the body of the loop that changes some part of the logical expression.
We will talk about three types of loops: while, do while, and for. The form
of a while loop is as follows:
while ( logical expression )
stmt;
Example 1:
int x = 7;
while ( x > 0 )
{
cout << x << endl;
x--;
}
Example 2 using data validation:
Suppose the user of a program is to input an integer in the range -10 to 10
(inclusive). Using data validation, write a section of code to input this value:
int k;
k = -99;
while ( k < -10 || k > 10 )
{
cout << "Enter an integer value
(between -10 and 10): ";
cin >> k;
}
Example 3:
Write a section of code that will display all multiples of 5 that are less
than 500.
int x = 5;
while ( x < 500 )
{
cout << x << endl;
x = x + 5;
}
That wraps up all I have to say about while loops so let's move on to the next
loop of interest. Read on for more about do while loops...
Do While Loops
A do while loop is another type of repetition statement. It is exactly the
same as the while loop except it does something and then evaluates the logical
expression of the loop to determine what happens next. Normally with a while
loop, a part of the logical expression in the loop must be initialized before
execution of the loop. A do while loop lets something be performed and then
checks the logical expression of the loop. I like to use a do while loop when
using data validation during a program. The form of a do while loop is as follows:
do
stmt(s);
while ( logical expression );
The stmt in the loop may be single or complex. Complex statements must be enclosed
with curly braces { }. Let's look at a couple of examples of do while loops.
Example 1:
int number;
do
{
cout << "Enter a postive number
greater than 0: ";
cin >> number;
}
while ( number <= 0 || int(number) != number );
Example 2:
int number;
do
{
cout << "Enter a number between
0 and 100: ";
cin >> number;
}
while ( number <= 0 || number >= 100 );
Having discussed while and do while loops, there is one more loop I would like
to cover: for loops. Read on for more about for loops...
For Loops
A for loop is another way to perform something that needs to be repeated in
C++ (repetition). Most programmers like to use for loops because the code can
be written in a more compact manner compared to the same loop written with
a while or do while loop. A for loop is also important to understand because
they are used when dealing with arrays and other topics in C++ [for info on
arrays see One-Dimensional Arrays (section 8) and Two-Dimensional Arrays (section
8)]. A for loop is generally used when you know exactly how many times a section
of code needs to be repeated. The general form of a for loop is as follows:
for ( expression1; expression2; expression3 )
stmt(s);
where stmt(s) is a single or compound statment. Expression1 is used to initialize
the loop; expression2 is used to determine whether or not the loop will continue;
expression3 is evaluated at the end of each iteration or cycle.
NOTE 1: expression2 is tested before the stmt and expression3 are executed;
it is possible that the body of the loop is never executed or tested.
NOTE 2: Any or all of the 3 expressions in a for loop can be omitted, but the
2 semi-colons must remain. If expression1 is omitted, there is no initialization
done in the loop, but you might not need any initialization for your program.
If expression2 is omitted, there is no test section so you will essentially
have an infinite loop. If expression3 is omitted, there is no update as part
of the for statement, but the update could be done as part of the statement
in the body of the loop.
In general, a for loop can be written as an equivalent while loop and vice
versa.
for ( expression1; expression2; expression3
)
stmt;
is equivalent to...
expression1;
while ( expression2 )
{
stmt(s);
expression3;
}
Example 1:
Write a for loop that will display all odd integers between 1 and 51:
for ( int k = 1; k <= 51; k += 2 )
cout << k << endl;
Example 2:
Write a for loop that will display a "countdown" of integers from 20 to 1:
for ( int k = 20; k >= 1; k-- )
cout << k << endl;
Now that I've covered while, do while, and for loops, I can introduce you to
some methods of controlling repetition in a program. Read on for more about
controlling repetition with sentinel values...