Back to CEO's Home Page

Control Structures II

Charles E. Oyibo

In Control Structures I, we explored how decisions are incorporated into programs (using the if, if...else, and switch structures). In this chapter we will discuss how repititions are incorporated into programs (specifically, using C++'s three repitition, or looping, structures that allow us to repeat a set of statements until certain conditions are met: the while, for, and do...while loops).

while Looping (Repitition) Structure

The general form of the while loop is:

while (expression)
    statement

The statement can be either a simple or compound statement (delimited by braces, {...}). The expression acts as a decision maker and is usually a logical expression. The statement is called the body of the loop. Note that the parentheses around the expression are part of the syntax.

The expression provides an entry condition. If it initially evaluates to true, the statement executes. The loop condition--the expression--is the reevaluated, and the statement (body of the loop) continues to execute until the expression is no longer true.

A loop that continues endless is is called an infinite loop. Always ensure that the loop's body contains statement(s) that assure that the exit condition--the expression in the while statement--will eventually be false.

Example:

i = 0;                  //Line 1
while ( i <= 20)        //Line 2
{
    cout << i << " ";   //Line 3
    i = i + 5;          //Line 4
}
cout << endl;

Sample Run:

0 5 10 15 20

At Line 1, the variable i is set to 0. The expression in the while statement (Line 2), i <= 20 is evaluated. Since the expression evaluates to true, the body of the while loop executes next. Line 3 outputs the value of i, (which is 0 in the first iteration), and Line 4 adds 5 to the value of i. The process of evaluating the (conditional) expression and executing the body of the while loop continues until the expression, i <= 20 no longer evalutes to true. Note that the variable in Line 2 is called the loop control variable.

Typically, while loops are written in the following form:

//initialize the loop control variable(s)
while (expression) // expression tests the loop control variable (lcv)
{
...
...
//update or reinitialize the loop control variable(s)
...
...
}

In some situation, we would want to store data on an external device such as a disk and instruct our program to read the data from the device. Let us assume that the data stored on the disk is free of errors and is not otherwise defective. There are four ways (we'll call them cases) to construct loops.

Case 1: Counter-Controlled while Loops

Suppose we know exactly how many pieces of data (or entries) need to be read and suppose further than the file has N data items. We could set up a counter (initialized to 0 before the while statement) to track how many items have been read. Before executing the body of the while statement, the counter is compared to N. If counter < N, the body of the while statement executes. The body of the loop continues to execute until the value of counter >= N. Thus, inside the body of the while statement, the value of counter increments after it reads a new item:

counter = 0; //initialize the loop control variable

while (counter < N) //test the loop control variable
{
    ...
    counter++; //update (increment) the loop control variable
    ...
}

The value of N (the number of items in the file) can be determined either by prompting the user for it or by specifying the first item in the file as the number of items in the file.

...program demonstrating counter-controlled while loops...

 

Case 2: Sentinel-Controlled while Loops

Suppose we do not know how many pieces of data (or entries) need to be read, but know the last entry is a special value (called a sentinel). In this case, we read the first item before the while statement. If this item does not equal the sentinel, the body of the while statement executes. The while statement continues to execute as long as the program has not read the sentinel:

cin >> variable // initialize the loop control variable

while (variable != sentinel) // test the loop control variable (against the sentinel)
{
    ...
    cin >> variable; // re-initialize the loop control variable
    ...
}

Case 3: Flag-Controlled while Loops

A flag-controlled while loop uses a bool variable to control the loop. Suppose found is a bool variable. The flag-controlled while loop takes the following form:

found = false; // initializes the loop control variable

while (!found) // test the loop control variable
{
...
if (expression)
found = true; // re-initialize the loop control variable
...
}

The variable found, which is used to control the execution of the while loop, is called a flag variable.

Case 4: EOF-Controlled while Loops

If the data file is frequently altered (e.g. if data is frequently added and deleted), it's best not to read the data with a sentinel value. Someone might accidentally erase the sentinel value or add data past the sentinel, especially if the programmer and data entry person are different people. In such cases (and in cases where we don't even know what the sentinel is) we could use an EOF (End Of File)-Controlled while loop.

The input stream variable can return a value after reading data, as follows:

  1. If the program has reached the end of the input data, the input stream variable returns the logical value false.
  2. If the program reads any faulty data (such as a char value in an int variable), the input stream enters the fail state. Once a stream enters the fail state, any further I/O operations using the stream are considered to be null operations; that is, they have no effect. The computer does not halt the program or give an error message; it just continues executing the program, silently ignoring each additional attempt to use that stream. In this case, the input stream variable returns the value false.
  3. In cases other than (1) and (2), the input stream variable returns the logical value true.

We can use the value returned by the input stream variable to determine whether the program has reached the end of the input data. Because the input stream variable returns the logical value true or false, in a while loop, it can be considered a logical expression:

cin >> variable; // initialize the loop control variable

while (cin) // test the loop control variable
}
    ...
    cin >> variable; // re-initialize the loop control variable
    ...
}

Notice that here, the variable cin acts as the loop control variable.

eof Function

In addition to checking the value of an input stream variable, such as cin, to determine whether the end of the file has been reached, C++ provides a function that we can use with an input stream variable to determine the end-of-file status. The function, eof, like the I/O functions (like get, ignore, peek) is a member of the data type istream. The syntax to use the function eof is:

istreamVar.eof()

where istreamVar is an input stream variable like cin.

...

 

for Looping (Repitition) Structure

The C++ for looping structure is a specialized form of the while loop. Its primary purpose is to simplify the writing of count-controlled loops. Thus, the for loop is typically called a counted or indexed for loop.

The general form of the for statement is:

for (initial statement; loop condition; update statement)
    statement

The initial statement, loop condition, and update statement (called for loop control statements) enclosed within paranthesis control the body (statement) of the for statement.

The for loop executes as follows:

  1. The initial statement executes.
  2. The loop condition is evaluated. If the loop condition evaluates to true
    1. Execute the for loop statement
    2. Execute the update statement
  3. Repeat Step 2 until the loop condition evaluates to false.

The initial statement usually initializes a variable (called the for loop control, or index, variable). It is the first statement to execute, and executes only once.

Example: The following for loop prints the first 10 non-negative integers:

for (i = 0; i < 10; i++)
    cout << i << " ";
    cout << endl;

...

Note that a for loop can have either a simple statement (as in the one above), or compound statements, delimited with braces, { and }. Note also that there is no semi-colon at the end of the for line. Placing a semi-colon at the end of the for line would cause the loop to execute 10 empty statements.

The following are some comments on for loops:

do...while Looping (Repitition) Structure

We now discuss the third type of looping or repitition structure. The general form of the do...while structure is:

do
  statement
while (expressions);

As usual, statement can either be a simple or compound statement (in which case it is enclosed between braces).

The statement executes first, and then the expression is evaluated. If the expression evaluates to true, the statement executes again. As long as the expression in a do...while statement is true, the statement executes.To avoid an infinite loop, we must, once again, make sure that the loop body contains a statement that ultimately makes the expression false and assures it exits properly.

Example:

int i = 0;
do
{
   cout << i << " ";
   i = i + 5;
}
while (i <= 20);

cout << endl;

The output of this code is:

0 5 10 15 20

 

In both while and for loops, the loop condition is evaluated before executing the body of the loop. Therefore, while and for loops are called pre-test loops. On the other hand, the loop condition in a do...while loop is executed after exiting the body of the loop. Therefore, do...while loops are called post-test loops.

Because the while and for loops both have entry conditions, these loops may never activate. The do...while loop, on the other hand, has an exit condition and therefore the body of this loop always executes at least once. The do...while loop is useful when it does not make sense to check a condition until after the action occurs.

break and continue Statements

The break statement, when executed in a switch structure, provides an immediate exit from the switch structure. Similarly, we can use the break statement in the while, for, and do...while loops. When the break statement executes in a repetition structure, it immediately executes from the structure. The break statement is typically used for two purposes:

After the break statement executes, the program continues to execute with the first statement after the structure. The use of the break statement in the loop can eliminate the use of certain (flag) variables...

The continue statement is used in while, for, and do...while structures. When the continue statement is executed in a loop, it skips the remaining statements in the loop and proceeds with the next iteration of the loop. In a while and do...while structure, the expression (that is, the loop-continue test) is evaluated immediately after the continue statement. In a for structure, the update statement is executed after the continue statement, and then the loop condition (that is, the loop-continue test) exectutes.

Nested Control Structures

By putting one control structure within another, we can achieve dramatic and fruitful results. Nesting of control structures takes on new power, subtlety, and complexity.

Top of page

Contact Information

Page Last Updated: Saturday February 12, 2005 10:21 AM