An Example of a Counting Loop (Repetition Structure)


Background:

Sometimes we want to repeat a process in a program a known number of times. This can be accomplished using a "counter controlled" loop. A variable is created to hold a "counter". This variable is initialized to hold a starting value which is then "incremented" (periodically increased by a fixed amount - often one) or "decremented" (periodically decreased by a fixed amount) each time that the program performs a "pass" (or "iteration") through the steps of the process (known as the loop's "body").

The step at which the loop starts is called its "entrance" and the last step performed before completion is called its "exit". Programmers have learned over the years that the conditional test that controls the exit from a loop should be placed either immediately following the entrance to the loop or following all steps in its body, but never in the middle of the body. Loops that have their tests in the middle are often error prone and difficult to debug. Loops with their tests at their entrance are said to use the "pretest (leading) decision" repetitious control structure (also called "while-do" by some people). Those with their tests after their entire body use the "posttest (trailing_ decision" type of repetitious control structure (also called "do-while" by some people). The C language offers a variety of statements to implement the two repetitive control structures.

Portions of the example below (including the flowchart, desk check, and C++ source code) have been duplicated in different background colors to illustrate the use of both of the repetitive structures discussed in class, "pretest decision" and "posttest decision". If you were writing this program, you would select only one of the two structures and document it.


PROBLEM STATEMENT:

"Display a list of whole numbers down the left edge of the screen that runs from 1 to 5."

Admittedly, this problem could be solved using a single statement in C++ of:

cout << "1\n2\n3\n4\n5\n";

But what if the objective was to repeat a list of 50 numbers or 5,000? Then, it would be far more efficient to write a single statement such as

cout << N << endl;

where N was an integer variable being used as a counter. The counter could be initalized at 1 and regularly incremented by 1 until it reached the top value. Each pass through the cout statement would be accompanied by a test of the condition that the counter was still less than the maximum (top) value. As long as the test of the condition remained true, control of the loop would pass back from the testing statement to the loop's entrance. But, when the test condition turned out to be false, control would exit from the loop and proceed to the next step in the program (in this example, its end).

DATA DEFINITION:

This program requires no user input. All values are known by the programmer in advance and can be set as constants in the code. Loops that base their decisions to repeat or exit on values that will always be known in advance (as opposed to those that may be entered by a user) are often described as using an "internal" method of control.

This task will require one integer variable to serve as a counter. Because it will be used to control the quantity of passes taken by the program through the single output statement, this variable is referred to as the "control variable". In this example, the control variable will also be involved in the output, although this is not always the case. Many control variables serve only to control the quantity of passes through a loop, but are not involved in the process that the loop performs.

Also be aware that not all loops count from 1 to 5, and not all of them increment by 1 each pass. Some count down. Some count by 2 or by 10, etc. Often, it is not the starting or stopping values of the counter (known as its "boundary values") that are important; but rather, the number of steps that occur as you count between them. For example, a loop that counts from 1 to 5 with an increment of 1 will perform the same number of passes as a loop that counts from 50 to 10 using a decrement of 10.

SAMPLE OUTPUT (Softcopy):

Note: In programs that involve repetitive processes (loops) be sure to provide sample output that shows more than one pass through the loop so that readers can see an example of the repetition taking place. This example involves only 5 passes, so all of the output is shown below. If this program counted from 1 to 500, then the sample softcopy would typically show a few lines at the beginning of the output and a few lines at the end, but not all 500 lines.

1
2
3
4
5

SYMBOLIC CONSTANT LIST:

We could use symbolic constants here to represent the starting and stopping values of the counter. In fact, we could also do the same with the amount of the increment. This would allow for easy revision to the program, making it more versatile.

LABEL DESCRIPTION DATA TYPE VALUE USAGE DESTINATION
First First line number Integer 1 Initialize Counter (C) ---
Final Final line number Integer 5 Compared to Counter (C) ---
Step Increment value for loop counter Integer 1 Loop increment ---

VARIABLE LIST:

LABEL DESCRIPTION DATA TYPE SOURCE USAGE DESTINATION
C Line number to be displayed Integer Set to First Loop index Screen

FLOWCHART FOR PROGRAM "count" USING THE PRETEST (LEADING) DECISION STRUCTURE:

When designing programs that use loops, we can illustrate the repetition structure through either an [outlined algorithm] or a diagram called a flowchart (see below). Such diagrams show the flow of control (or order of execution) of the steps within a program and can be used instead of an outline when developing and documenting an algorithm. Students are advised to read the basic web page about Flowcharting Symbols & Guidelines. The flowchart below illustrates a repetition structure based on the value stored in a control variable named C. The diamond shape encloses the condition that is being tested. The processes leading out of the diamond are called branches or legs and must be labeled to indicate which one is to be followed when the condition in the diamond is TRUE or FALSE. It is typical to define the condition such that it will be true for the branch that passes through the loop body and false for the branch that exits the loop.

Flowchart of a leading decision counting loop

TEST OUTPUT (for the Pretest Decision solution):

1
2
3
4
5

TRACING CHART (for the Pretest Decision solution)

Readers who have difficulty rendering tracing charts can read the [text-based tracing list] for this example instead.

Data Tracing Charts are used to document what would be happening in the computer's memory during the execution of the steps described in an algorithm. A column is provided for each variable in your analysis and for each condition being tested (in a diamond shape). An additional column can be added on the left of the table to serve as a reference to steps in your flowchart if you choose to put reference letters next to the related shapes. This was not done in the example shown below. The entries in the chart below relate to only steps in the algorithm that effect the memory.

CC<=Final
1 
 True
2 
 True
3 
 True
4 
 True
5 
 True
6 
 False

C++ SOURCE CODE (for the Leading Decision solution):

/* count.c */
/* a repetitive process using the Leading Decision structure */
/* by Randolph Gibson - 9 October 2001 */

#include <iostream>  /* Standard Input/Output header file */
using namespace std;
#define First 1     /* Starting value for counter */
#define Final 5     /* Final value for counter */
#define Step 1      /* Value to increase by each pass of loop */

int C;  /* Counter: Line number to be displayed */

int main (void)
{
  C = First; /* Initialize counter to starting value */
  while (C<=Final)        /* Test for repetition/exit BEFORE the body */
    {                     /* Start a pass through the loop */
      cout << C << endl;  /* This step is the "body" of the loop */
      C = C + Step;       /* Increment C by the step amount */
    }                     /* End the pass through the loop */
  return 0;               /* Return zero error code to parent process */
}

FLOWCHART FOR THE PROGRAM "count" USING THE POSTTEST (TRAILING) DECISION STRUCTURE:

We can illustrate the posttest decision repetition structure through either an [outlined algorithm] or the flowchart below.

Flowchart of a trailing decision counting loop

TEST OUTPUT (for the Posttest Decision solution):

1
2
3
4
5

TRACING CHART (for the Posttest Decision solution)

Readers who have difficulty rendering tracing charts can read the [text-based tracing list] for this example instead.

CC<=Final
1 
2 
 True
3 
 True
4 
 True
5 
 True
6 
 False

C++ SOURCE CODE (for the Trailing Decision solution):

/* count.c */
/* a repetitive process using the Trailing Decision structure */
/* by Randolph Gibson - 9 October 2001 */

#include <iostream>  /* Standard Input/Output header file */
using namespace std;

#define First 1     /* Starting value for counter */
#define Final 5     /* Final value for counter */
#define Step 1      /* Value to increase by each pass of loop */

int C;  /* Counter: Line number to be displayed */

int main (void)
{
  C = First; /* Initialize counter to starting value */
  do
    {                      /* Start a pass through the loop */
      cout << C << endl;   /* This step is the "body" of the loop */
      C = C + Step;        /* Increment C by the step amount */
    }                      /* End the pass through the loop */
  while (C<=Final);        /* Test for repetition/exit AFTER the body */
  return 0;                /* Return zero error code to parent process */
}
PATH: Instructional Server> COP 2000> Examples>