Professional Documents
Culture Documents
Program Flow Controls: Hapter Hree
Program Flow Controls: Hapter Hree
Program Flow Controls: Hapter Hree
CHAPTER THREE
Program Flow Controls
3.1 Introduction
A running program spends all of its time executing instructions or statements in that program.
The order in which statements in a program are executed is called flow of that program.
Programmers can control which instruction to be executed in a program, which is called flow
control. The process of performing one statement after another is called the flow of execution or
flow of control. The term flow control reflects the fact that the currently executing statement has
the control of the CPU, which when completed will be handed over (flow) to another statement.
Flow control in a program is typically sequential, which is the most common and straight-
forward, where programming statements are executed in the order that they are written - from top
to bottom in a sequential manner. But a program is usually not limited to a linear sequence of
instructions. During its process the program will have an execution that might be divided to other
paths by branching statements. Or perform a block of statement repeatedly until a condition
fails by Repetition or looping.
Flow control is an important concept in programming because it will give all the power to the
programmer to decide what to execute during a run and what is not, therefore, affecting the
overall outcome of the program. Shortly it is a way to alter the natural sequence of execution in a
program. In other words, they act as “direction signals” to control the path a program takes. For
that purpose, C++ provides control structures that serve to specify what has to be done by our
program, when and under which circumstances.
There are three basic flow control constructs - sequential, conditional (or decision),
and loop (or iteration), as illustrated below.
statement1;
statement2;
statement3;
From the compiler’s perspective, a block statement is equivalent to a single statement. Block
statements can be nested inside other block statements
Most of the control structures that we will see in this section require a generic statement as part
of its syntax. A statement can be either a simple statement (a simple instruction ending with a
semicolon) or a compound statement (several instructions grouped in a block), like the one just
described. In the case that we want the statement to be a simple statement, we do not need to
enclose it in braces ({}). But in the case that we want the statement to be a compound statement
it must be enclosed between braces ({}), forming a block.
if statement,
switch-case
conditional expression
If expression returns true, the statement or the block is executed and then next statement(s)
get executed.
If expression returns false, the statement or the block is not executed and the program
continues at execution of next statement(s).
Print “Passed”
This pseudocode determines whether the condition "student’s grade is greater than or equal to
60" is true or false. If the condition is true, then "Passed" is printed and the next pseudocode
statement in order is "performed" (remember that pseudocode is not a real programming
language). If the condition is false, the print statement is ignored and the next pseudocode
statement in order is performed. Note that the second line of this selection structure is indented.
Such indentation is optional, but it is highly recommended because it emphasizes the inherent
structure of structured programs.
if ( grade > = 6 0 )
cout<<" Passed " ;
Example:
1 if (mark >= 50) {
2 cout << "Congratulation!" << endl;
3 cout << "Keep it up!" << endl;
4
}
5
if (expression){
statement1 / block1
}
else{
statement2 / block2;
}
next statement(s);
For example, the following code fragment prints Congratulation! and keep it up! on separate line
only if the value stored in the mark variable is greater than or equal to 50:
1 if (mark >= 50) { Note:
2 cout << "Congratulation!" << endl; You could omit races { }, if there is only
3 cout << "Keep it up!" << endl; one statement inside block. However, it
4 } recommendable to keep the braces, even
else { though there is only one statement in the
cout << "Try Harder!" << endl; block, to improve the readability of your
} program.
Example 1:
int num1 = 5, num 2 = 6, min, max;
min = num1 < num2 ? num1 : num2 // returns min = 5
max = num1 < num2 ? num1 : num2 // returns max = 6
Example 2:
cout << mark >= 50 ? "PASS" : "FAIL" << endl;
// return either "PASS" or "FAIL", and put to cout stream
When if..else statements are nested, the compiler uses the following rule to parse the compound
statement:
Match each else with the last unmatched if.
A frequently-used form of nested if statements involves the else part consisting of another if-else
statement. For example: nested if…else statements to check if a character is a digit, upper letter,
lower letter or special character:
if (ch >= '0' && ch <= '9')
kind = digit;
else {
if (ch >= 'A' && ch <= 'Z')
kind = upperLetter;
else {
if (ch >= 'a' && ch <= 'z')
kind = lowerLetter;
else
kind = special;
}
}
Nested if … else statements are often used to test a sequence of parallel alternatives, where only
the else clauses contain further nesting. In that case, the resulting compound statement is usually
formatted by lining up the else if phrases to emphasize the parallel nature of the logic.
The switch statement has four components: Switch, Case, Default, Break, where Default and
Break are Optional.
When match is found the group of statements following the matching case is then executed
until it finds the break statement. When it finds this break statement the program jumps to
the end of the switch selective structure. The break; statement tells the computer to exit the
switch statement
Finally, if the value of expression did not match any of the previously specified case values
(you can include as many case labels as values you want to check), the program will
execute the statements included after the default case, if it exists (since it is optional).
Department of Software Engineering, AASTU Page 7
Fundamentals of Programming I
Both of the following code fragments have the same behavior:
switch example if-else equivalent
switch (x) { if (x == 1) {
case 1: cout << "x is 1";
cout << "x is 1"; }
break; else if (x == 2) {
case 2: cout << "x is 2";
cout << "x is 2";
break; }
default: else {
cout << "value of x unknown"; cout << "value of x unknown";
} }
The switch statement is a bit peculiar within the C++ language because it uses labels instead of
blocks. This forces us to put break statements after the group of statements that we want to be
executed for a specific condition. Otherwise the remainder statements including those
corresponding to other labels will also be executed until the end of the switch selective block or a
break statement is reached.
For example, suppose we have parsed a binary arithmetic operation into its three components
and stored these in variables operator, operand1, and operand2. The following switch statement
performs the operation and stores the result in result.
switch (operator) {
case '+': result = operand1 + operand2;
break;
case '-': result = operand1 - operand2;
break;
case '*': result = operand1 * operand2;
break;
case '/': result = operand1 / operand2;
break;
default: cout << "unknown operator: " << ch << '\n';
break;
}
As illustrated by this example, if we did not include a break statement after the first group for
case one, the program will not automatically jump to the end of the switch selective block rather
it would continue executing the rest of statements until it reaches either a break instruction or the
end of the switch selective block.
Even if it is usually necessary to include a break statement at the end of each case, there are,
however, situations in which it makes sense to have a case without a break. For example, if we
extend the above statement to also allow x (both lower and upper case) to be used as a
multiplication operator, we will have:
switch (operator) {
case '+': result = operand1 + operand2;
break;
case '-': result = operand1 - operand2;
break;
case 'x':
case 'X':
case '*': result = operand1 * operand2;
break;
case '/': result = operand1 / operand2;
break;
default: cout << "unknown operator: " << ch << '\n';
break;
}
Because case 'x' and case ‘X’ has no break statement (in fact no statement at all!), when this case is
satisfied, execution proceeds to the statements of the next case and the multiplication is
performed.
It should be obvious that any switch statement can also be written as multiple if-else statements.
So that the above statement, for example, may be written as:
if (operator == '+')
result = operand1 + operand2;
else if (operator == '-')
result = operand1 - operand2;
else if (operator == 'X' || operator == 'x' || operator == '*')
result = operand1 * operand2;
else if (operator == '/')
result = operand1 / operand2;
else
cout << "unknown operator: " << ch << '\n';
Notice that switch can only be used to compare an expression against constants. Therefore we
cannot put variables as labels (e.g. case n: where n is a variable) or ranges like case (1. .3):
because they are not valid C++ constants. If you need to check ranges or values that are not
constants, use a concatenation of if ... else if statements.
In general, preference should be given to the switch version when possible. The if-else
approach should be reserved for situation where a switch cannot do the job.
3.4 Looping
In general, statements are executed sequentially; the first statement in a function is executed first,
followed by the second, and so on. However, there may be a situation, when you need to execute
a block of code several times - looping. Such programming statements are called loops, because
the flow of execution “loops back” to the beginning of the block.
A loop statement allows us to execute a statement or group of statements multiple times and
following is the general from of a loop statement in most of the programming languages:
There are two essentially different ways of knowing when a loop has been repeated enough times.
a) When you know exactly how many loops you want to make.
o The counter is increased by a fixed amount (usually by 1) each time the loop is
executed.
An example of this would be if you wished this program to print the word Hello
exactly 7 times.
Repeat a statement or block until a condition within the loop body changes that cause the
repetition to stop.
o Sentinel controlled: Keep processing data until a special value (sentinel value)
that is not a possible data value is entered to indicate that processing should stop.
o Flag controlled: Keep processing data until the value of a flag changes in the
loop body.
C++ programming language provides the following types of loop to handle looping
requirements.
1. The for loop
2. The while loop
3. The do … while loop
The control of the for loop appear in parentheses and is made up of three parts.
The first part, the initialization_expression, used to declare and/or initialize control
variable(s) (i.e. sets the initial conditions) for the loop, particularly the loop counter. It is
evaluated first, before any iteration occurs for the loop. Also executed only once.
The third part of the control information, the increment_expression also called update
expression, is usually used to increment the loop counter (i.e. to update the control
variable(s)). This is executed at the end of each loop iteration and its main function is to
repeat statement while condition remains true.
Note that the for loop provides specific locations to contain an initialization statement and an
increase statement. So this loop is specially designed to perform a repetitive action with a
counter which is initialized and increased on each iteration.
2. Next the condition is checked. If it is true the loop continues, otherwise the loop ends and
statement is skipped (not executed).
5. Finally, the loop gets back to step 2 and repeat through step 4.
The following for loop, for example, countdown start from 10 up to 1 and also calculates the sum
of all integers from 1 to n.
int n;
cout << "Enter a positive integer: ";
cin >> n;
long sum=0;
Any of the three expressions in a for loop may be empty; especially the initialization and update
expression are optional. They can remain empty, but in all cases the semicolon signs between
them must be written.
for (;;) infinite loop:- Removing all the expressions gives us an infinite loop
For example, suppose that we wanted to initialize more than one variable in our loop:
This loop will execute for 50 times if neither n or i are modified within the loop. In this loop
statement n starts with a value of 0, and i with 100, the condition is n!=i (i.e. n is not equal to i).
Because n is increased by one and i decreased by one, on every iteration of the loop; the
condition expression will become false after the 50th loop, when both n and i will be equal to 50.
Because loops are statements, they can appear inside other loops. In other words, loops can be
nested. For example,
for (inti = 1; i<= 3; ++i)
{
for (int j = 1; j <= 3; ++j)
{
cout << '(' << i << ' , ' << j << ") : ";
}
}
The above code segment produces the product of the set {1, 2, 3} with itself, giving the output:
(1 , 1) : (1 , 2) : (1 , 3) : (2 , 1) : (2 , 2) : (2 , 3) : (3 , 1) : (3 , 2) : (3 , 3)
Scope of variables
int main(){
int n;
cout << "Enter a positive integer: ";
cin >> n;
long sum=0; //global variable
for (int i = 1; i < n/2; i++) // the scope of this i is this loop
{
sum += i;
for (int i = n/2; i <= n; i++) // the scope of this i is this loop
{
sum += i;
cout << "The sum of the first " << n << " integers is "<< sum << endl;
}
}
}
Examples:
a) This program finds the maximum of a sequence of input numbers using a Sentinel to Control
a for Loop:
int main(){
int n, max;
cout << "Enter positive integers (0 to quit): ";
cin >> n;
for (max = n; n > 0; ){
if (n > max) max = n;
cin >> n;
}
cout << "max = " << max << endl;
}
while (expression)
{
//statement(s)
}
In this case, the expression (called the loop condition) is evaluated and then statement(s) (called
the loop body) is executes as long as this given logical expression between parentheses is true
(i.e. the outcome is nonzero) and the whole process is repeated. Otherwise, the loop is terminated
(i.e. when expression is false, execution continues with the statement following the loop block).
Note that the expression is tested at the beginning of the loop, so if it is initially false, the loop
will not be executed at all.
The whole process of the previous program can be interpreted according to the following script
(beginning in main):
When creating a while-loop, we must always consider that it has to end at some point, therefore
we must provide within the block some method to force the condition to become false at some
point, otherwise the loop will continue looping forever. In this case we have included --n; that
decreases the value of the variable that is being evaluated in the condition (n) by one, and this
will eventually make the condition (n>0) to become false after a certain number of loop
iterations: to be more specific, when n becomes 0, that is where our while-loop and our
countdown end.
Of course this is such a simple action for our computer that the whole countdown is performed
instantly without any practical delay between numbers.
Another example, suppose we wish to calculate the sum of all numbers from 1 to some integer
denoted by n. This can be expressed as:
i = 1;
sum = 0;
while (i <= n){
sum += i;
++i;
}
1st 1 5 true 1 2
2nd 2 5 true 3 3
3rd 3 5 true 6 4
4th 4 5 true 10 5
5th 5 5 true 15 6
6th 6 5 true 21 7
7th 7 true 28 8
8th 8 true 36 9
9th 9 true 45 10
10th 10 true 55 11
11th 11 false
It is not unusual for a while loop to have an empty body (i.e., a null statement). The following
loop, for example, sets n to its greatest odd factor.
Here the loop condition provides all the necessary computation, so there is no real need for a
body. The loop condition not only tests that n is even, it also divides n by two, display the value
of n on screen and ensures that the loop will terminate should n be zero.
Note: if you do not put the either curly brace (i.e. {}) or semicolon (;) after while loop as shown
on the example above to indicate that the loop have an empty body it will automatically execute
the statement after it repeatedly until the loop condition get false.
do{
statement(s);
}while(expression);
First statement(s) is executed and then expression is evaluated. If the outcome of the expression
is nonzero then the whole process is repeated. Otherwise, the loop is terminated.
The do loop is less frequently used than the while loop. It is useful for situations where we need
the loop body to be executed at least once, regardless of the loop condition. For example,
suppose we wish to repeatedly read a value and print its square, and stop when the value is zero.
This can be expressed as the following loop:
The difference between while loop and do-while loop lies in the order of the body and condition.
In while-do, the condition is tested first. The body will be executed if the condition is true and
the process repeats. In do-while, the body is executed and then the condition is tested. Take note
that the body of do-while will be executed at least once (vs. possibly zero for while-do).
Suppose that your program prompts user for a number between 1 to 10, and checks for valid
input, do-while with a Boolean flag could be more appropriate.
// Game loop
bool gameOver = false;
while (!gameOver) {
// play the game
......
// Update the game state
// Set gameOver to true if appropriate to exit the game loop
......
}
Unlike the while loop, the do...while loop is never used in situations where it would have a null
body. Although a do...while loop with a null body would be equivalent to a similar while loop,
the latter is always preferred for its superior readability.
int main()
{
int sum = 0; // Store the accumulated sum
int upperbound;
cout << "Enter the upperbound: ";
cin >> upperbound;
/* Prompt user for positive integers and display the count, maximum,
minimum and average. Terminate the input with -1 (StatNumbers.cpp) */
#include <iostream>
#include <climits> // for INT_MAX
#include <iomanip> // for setprecision(n)
using namespace std;
int main() {
int numberIn; // input number (positive integer)
In this example, we use -1 as the sentinel value to indicate the end of inputs, which is a sequence
of positive integers. Instead of hard coding the value of -1, we use a variable called sentinel for
flexibility and ease-of-maintenance.
Department of Software Engineering, AASTU Page 22
Fundamentals of Programming I
(4) Nested Loops
You can nest loops of any kind one inside another to any depth. The following diagram
illustrates a nested for-loop, i.e., an inner for-loop within an outer for-loop.
int totalCount = 70
while(totalCount<600){
for(int i = 0; i < 10; i++){
totalCount += i;
if(totalCount>400)
break;
}
}
Exercise: Try out the following program, which prints a 6-by-8 checker box pattern
using nested loops, as follows:
########
########
########
########
########
Example (break): The following program lists the non-prime numbers between 2 and an
upper-bound.
// List non-prime from 1 to an upperbound (NonPrimeList.cpp).
#include <iostream>
#include <cmath>
using namespace std;
int main(){
int upperbound;
cout << "Enter the upperbound: ";
cin >> upperbound;
for (int number = 2; number <= upperbound; ++number)
{
// Not a prime, if there is a factor between 2 and sqrt(number)
int maxFactor = (int)sqrt(number);
for (int factor = 2; factor <= maxFactor; ++factor)
{
if (number % factor == 0) // Factor?
{
cout << number << " ";
break; // A factor found, no need to search for more factors
}
}
}
cout << endl;
return 0;
}
A break statement only applies to the “loop” or “switch” immediately enclosing it. It is an error
to use the break statement outside a loop or a switch statement.
/*
* List primes from 1 to an upperbound (PrimeList.cpp).
*/
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int upperbound;
cout << "Enter the upperbound: ";
cin >> upperbound;
In while and do while loops, the next iteration commences from the loop condition; where in a
“for” loop, the next iteration commences from the loop’s third expression.
Example (continue):
while(true)
{
for(i=0; i<n; i++)
{
cin>>num;
if(num < 0)
continue; //causes a jump to : i++
sum += number;
}
}
Note: Break and continue are poor structures as they are hard to read and hard to follow. Use
them only if absolutely necessary. You can always write the same program without
using break and continue.
The destination point is identified by a label, which is then used as an argument for the goto
statement. It has the general form:
goto label;
where label is a valid identifier which marks the jump destination point of goto statement. The
label should be followed by a colon and appear before a statement within the same function as
the goto statement itself.
For example, here is our countdown loop using goto:
Generally speaking, this instruction has no concrete use in structured or object oriented
programming aside from those that low-level programming fans may find for it.
The exitcode is used by some operating systems and may be used by calling programs. By
convention, an exit code of 0 means that the program finished normally and any other value
means that some error or unexpected results happened.
int main() {
...
if (errorCount > 10) {
cout << "too many errors" << endl;
return -1; // Terminate and return control to OS from
main()
}
...
}
Exercises 1:
Print these patterns using nested loop (in a program called PrintPattern1x). Use a variable
called size for the size of the pattern and try out various sizes. You should use as few printing
statements as possible.
if (i == 0)
if (j == 0)
cout << "i and j are zero" << endl;
else cout << "i is not zero" << endl; // intend for the outer-if
The else clause in the above codes is syntactically applicable to both the outer-if and the inner-if.
The C++ compiler always associate the else clause with the innermost if (i.e., the nearest if).
Dangling else can be resolved by applying explicit parentheses. The above codes are logically
incorrect and require explicit parentheses as shown below.
if ( i == 0)
{
if (j == 0) cout << "i and j are zero" << endl;
}
else
{
cout << "i is not zero" << endl; // non-ambiguous for outer-if
}
It is commonly used. It seems to be an endless loop (or infinite loop), but it is usually terminated
via a break or return statement inside the loop body. This kind of code is hard to read - avoid if
possible by re-writing the condition
setw(int field-widht): set the field width for the next IO operation. setw() is non-sticky and
must be issued prior to each IO operation. The field width is reset to the default after each
operation (with just enough width to accommodate the field).
setfill(char fill-char): set the filled character for padding to the field width.
boolalpha/noboolalpha (for bool): display bool values as alphabetic string (true/false) or 1/0
int main() {
string areaCode, phoneCode;
string inStr;
cout << "Enter your phone number in this format (xxx)xxx-xxxx : ";
cin.ignore(); // skip '('
cin >> setw(3) >> areaCode;
cin.ignore(); // skip ')'
cin >> setw(3) >> phoneCode;
cin.ignore(); // skip '-'
cin >> setw(4) >> inStr;
phoneCode += inStr;