Previous | Next | Table of Contents | Index | Program List | Copyright

5.1 Control Structures: Counting Loops and the FOR Statement

Just as the ability to make decisions is a very important programming tool, so is the ability to specify that a group of operations is to be repeated. For example, a company with seven employees will want to repeat the gross pay and net pay computations in its payroll program seven times, once for each employee.

The repetition of steps in a program is called a loop. The loop body contains the steps to be repeated. Ada provides three control statements for specifying repetition. This chapter examines the FOR statement and previews the WHILE statement. The WHILE statement and the third loop form, the general LOOP statement, are examined in Chapter 6.

The FOR Statement

The FOR statement can be used to specify some forms of repetition quite easily, as shown in the next examples.

Example 5.1

The statement

    FOR Count IN 1..5 LOOP
      Ada.Text_IO.New_Line;
    END LOOP;

has the same effect as the five statements

    Ada.Text_IO.New_Line;
    Ada.Text_IO.New_Line;
    Ada.Text_IO.New_Line;
    Ada.Text_IO.New_Line;
    Ada.Text_IO.New_Line;

The FOR statement above causes the New_Line operation to be performed five times. The FOR statement is used to implement counting loops, which are loops where the exact number of loop repetitions can be specified as a variable or constant value. Here, the number of repetitions required was five. The reserved words END LOOP terminate the FOR statement.

The FOR statement specifies that the variable Count should take on each of the values in the range 1 to 5 during successive loop repetitions. This means that the value of Count is 1 during the first loop repetition, 2 during the second loop repetition, and 5 during the last loop repetition.

Count is called a loop counter because its value controls the loop repetition. In our example, the loop counter is intialized to 1 when the FOR statement is first reached; after each execution of the loop body, the loop counter is incremented by 1 and tested to see whether loop repetition should continue.

Unlike other variables, a FOR loop counter is not declared. A loop counter may also be referenced in the loop body, but its value cannot be changed by statements in the loop body. Example 5.3 shows a FOR statement whose loop counter is referenced in the loop body.

Example 5.2

The following FOR loop displays a sequence of HowMany asterisks. If HowMany has a value of 5, 5 asterisks in a row will be displayed; if HowMany has a value of 27, 27 asterisks will be displayed, and so on.

FOR Count IN 1 .. HowMany LOOP
  Ada.Text_IO.Put(Item => '*');
END LOOP;

Example 5.3

Program 5.1 uses a FOR loop to print a list of integer values and their squares. During each repetition of the loop body, the statement NumSquared := Num**2; computes the square of the loop counter Num; then, the values of Num and NumSquared are displayed. A trace of this program is shown in Table 5.1.

Program 5.1
Squares

WITH Ada.Text_IO;
WITH Ada.Integer_Text_IO;
PROCEDURE Squares IS
------------------------------------------------------------------------
--| Displays a list of integer values and their squares.
--| Author: Michael B. Feldman, The George Washington University
--| Last Modified: July 1995
------------------------------------------------------------------------

  MaxNum : CONSTANT Natural := 10;
  NumSquared : Natural;   -- output - square of Num

BEGIN -- Squares

  Ada.Text_IO.Put(Item => "        Num    Num ** 2 ");
  Ada.Text_IO.New_Line;
  Ada.Text_IO.Put(Item => "        ---    ---------");
  Ada.Text_IO.New_Line;

  FOR Num IN 1..MaxNum LOOP
    NumSquared := Num ** 2;
    Ada.Integer_Text_IO.Put (Item => Num, Width => 10);
    Ada.Integer_Text_IO.Put (Item => NumSquared, Width => 10);
    Ada.Text_IO.New_Line;
  END LOOP;

END Squares;
Sample Run
        Num    Num ** 2 
        ---    ---------
         1         1
         2         4
         3         9
         4        16
         5        25
         6        36
         7        49
         8        64
         9        81
        10       100
The trace in Table 5.1 shows that the loop counter Num is initialized to 1 when the FOR loop is reached. After each loop repetition, Num is incremented by 1 and tested to see whether its value is still less than or equal to MaxNum (4). If the test result is true, the loop body is executed again, and the next values of Num and NumSquared are displayed. If the test result is false, the loop is exited. Num is equal to MaxNum during the last loop repetition. After this repetition, the value of Num becomes undefined (indicated by ? in the last table line), and the loop is exited. The counter Num ceases to exist and cannot be referenced again unless the loop is entered again, in which case the counter is given a new existence.

Table 5.1
Trace of Program 5.1

Statement			Num	Square		Effect

? ? FOR Num IN 1..MaxI LOOP 1 Initialize Num to 1 Square := Num**2; 1 Assign 1 * 1 to Square Ada.Integer_Text_IO.Put(Item=>Num,Width=>10); Display 1 Ada.Integer_Text_IO.Put(Item=>Square,Width=>10); Display 1
Increment and test Num 2 2 <= 4 is true Square := Num**2; 4 Assign 2 * 2 to Square Ada.Integer_Text_IO.Put(Item=>Num,Width=>10); Display 2 Ada.Integer_Text_IO.Put(Item=>Square,Width=>10); Display 4
Increment and test Num 3 3 <= 4 is true Square := Num**2; 9 Assign 3 * 3 to Square Ada.Integer_Text_IO.Put(Item=>Num,Width=>10); Display 3 Ada.Integer_Text_IO.Put(Item=>Square,Width=>10); Display 9
Increment and test Num 4 4 <= 4 is true Square := Num**2; 16 Assign 4 * 4 to Square Ada.Integer_Text_IO.Put(Item=>Num,Width=>10); Display 4 Ada.Integer_Text_IO.Put(Item=>Square,Width=>10); Display 16
Increment and test Num ? Exit loop

It is also possible to count backward in a FOR loop. Writing IN REVERSE instead of IN causes the loop counter to start at its maximum value and be decremented by 1, instead of incremented, in each loop iteration.

Example 5.4:

Program 5.2 is a modification of Program 5.1. This time the largest number MaxNum is read from the terminal, and the squares are printed from the largest down to the smallest. The loop statement

FOR Num IN REVERSE 1..MaxNum LOOP

controls the iteration. The first value of MaxNum is the number entered at the keyboard.

Program 5.2
Finding the Squares in Reverse Order

WITH Ada.Text_IO;
WITH Ada.Integer_Text_IO;
PROCEDURE Reverse_Squares IS
------------------------------------------------------------------------
--| Displays a list of integer values and their squares, 
--| in reverse order  
--| Author: Michael B. Feldman, The George Washington University
--| Last Modified: July 1995
------------------------------------------------------------------------

  MaxNum :     Positive;
  NumSquared : Natural;   -- output - square of Num
 
BEGIN -- Reverse_Squares

  Ada.Text_IO.Put
    (Item => "Enter the largest integer you wish to square > ");
  Ada.Integer_Text_IO.Get(Item => MaxNum);

  Ada.Text_IO.Put(Item => "        Num    Num ** 2 ");
  Ada.Text_IO.New_Line;
  Ada.Text_IO.Put(Item => "        ---    ---------");
  Ada.Text_IO.New_Line;

  FOR Num IN REVERSE 1..MaxNum LOOP
    NumSquared := Num ** 2;
    Ada.Integer_Text_IO.Put (Item => Num, Width => 10);
    Ada.Integer_Text_IO.Put (Item => NumSquared, Width => 10);
    Ada.Text_IO.New_Line;
  END LOOP;

END Reverse_Squares;
Sample Run
Enter the largest integer you wish to square > 13
        Num    Num ** 2 
        ---    ---------
        13       169
        12       144
        11       121
        10       100
         9        81
         8        64
         7        49
         6        36
         5        25
         4        16
         3         9
         2         4
         1         1

SYNTAX DISPLAY
Counting Loops (Simplest Form)

Forms:
FOR counter IN 1..repetitions LOOP 
	statement sequence
END LOOP;
FOR counter IN REVERSE 1..repetitions LOOP 
	statement sequence
END LOOP;

Example:
FOR I IN 1 .. HowMany LOOP
	Ada.Integer_Text_IO.Put (Item => I, Width => 5);
	Ada.Text_IO.New_Line;
END LOOP;

Interpretation:
The number of times statement sequence is executed is determined by the value of repetitions. The value of the loop counter counter is set to 1 before the first execution of statement sequence; counter is incremented by 1 after each execution of statement sequence. Repetitions must be an expression, constant, or variable with an integer value.

If REVERSE is present, as in the second form above, counter is initialized to repetitions before the first execution of statement sequence, then decremented by 1 after each execution of statement sequence.

Note: If the value of repetitions is less than 1, statement sequence will not be executed. No statement within statement sequence can change the value of counter. The variable counter is not declared separately and has no existence outside the loop.

Accumulating a Sum

We can use a counting loop to accumulate the sum of a collection of data values as shown in the next problem.


Case Study: Sum of Integers

PROBLEM SPECIFICATION

Write a program that finds the sum of all integers from 1 to N.

ANALYSIS

In order to solve this problem, it will be necessary to find some way to form the sum of the first N positive integers.

Data Requirements

Problem Inputs

the last integer in the sum (N : Positive)

Problem Outputs

the sum of integers from 1 to N (Sum : Natural)

DESIGN

Initial Algorithm

1. Prompt the user for the last integer (N).

2. Find the sum (Sum) of all the integers from 1 to N inclusive.

3. Display the sum.

Algorithm Refinements

Step 2 Refinement

2.0. Set Sum to zero

2.1. Add 1 to Sum

2.2. Add 2 to Sum

2.3. Add 3 to Sum

. . .

2.N. Add N to Sum

For a large value of N, it would be rather time-consuming to write this list of steps. We would also have to know the value of N before writing this list; consequently, the program would not be general, since it would work for only one value of N.

Because steps 2.1 through 2.N are all quite similar, we can represent each of them with the general step

2.i. Add i to Sum

This general step must be executed for all values of i from 1 to N, inclusive. This suggests the use of a counting loop with i as the loop counter.

Program Variables:

loop counter--represents each integer from 1 to N (i : Positive).

The variable i will take on the successive values 1, 2, 3, ...,N. Each time the loop is repeated, the current value of i must be added to Sum. We now have a new refinement of step 2.

Step 2 Refinement

2.1.

    FOR each integer i from 1 to N LOOP 
	Add i to Sum
    END LOOP;

TEST PLAN

What should happen if a zero is entered for N? A negative number? You should predict the results and test to see if your predictions were correct.

IMPLEMENTATION

The complete program is shown in Program 5.3. The statements

    Sum := 0; -- Initialize Sum to zero
    FOR I IN 1 .. N LOOP
    	Sum := Sum + I ; -- Add the next integer to Sum
    END LOOP;

are used to perform step 2. In order to ensure that the final sum is correct, the value of Sum must be initialized to zero (algorithm step 2.0) before the first addition operation. The FOR statement causes the assignment statement Sum := Sum + I; to be repeated N times. Each time, the current value of I is added to the sum being accumulated and the result is saved back in Sum. Note that Sum must be of type Natural, rather than Positive, in order to initialize it to zero.

Program 5.3
Sum of Integers from 1 to N

WITH Ada.Text_IO;
WITH Ada.Integer_Text_IO;
PROCEDURE Sum_Integers IS
------------------------------------------------------------------------
--| Finds and displays the sum of all positive integers from 1 to N.
--| Author: Michael B. Feldman, The George Washington University 
--| Last Modified: July 1995
------------------------------------------------------------------------
 
  N   : Positive;            -- input  - the last integer added
  Sum : Natural;             -- output - the sum being accumulated
 
BEGIN -- Sum_Integers 

  -- Read the last integer, N
  Ada.Text_IO.Put (Item => "Enter the last integer in the sum > ");
  Ada.Integer_Text_IO.Get (Item => N);
 
  -- Find the sum (Sum) of all integers from 1 to N
  Sum := 0;            -- Initialize Sum to 0
  FOR I IN 1 .. N LOOP
    Sum := Sum + I;    -- Add the next integer to Sum
  END LOOP;

  -- Display the sum
  Ada.Text_IO.Put (Item => "The sum of the integers from 1 to ");
  Ada.Integer_Text_IO.Put (Item => N, Width => 1);
  Ada.Text_IO.Put (Item => " is ");
  Ada.Integer_Text_IO.Put (Item => Sum, Width => 1);
  Ada.Text_IO.New_Line;

END Sum_Integers;
Sample Run
Enter the last integer in the sum > 25
The sum of the integers from 1 to 25 is 325
A trace of the program for a data value of 3 is shown in Table 5.2. The trace verifies that the program performs as desired because the final value stored in Sum is 6 (1+2+3). The loop counter I ceases to exist after it reaches the value of N (3 in this case). As shown in the table, the statement Sum := Sum + I; is executed exactly three times.

Table 5.2
Trace of Program 5.2

Statement				i	N	SUM	Effect

Ada.Text_IO.PUT(Item=>"Enter.."); ? ? ? Ada.Integer_Text_IO.Get(Item => N); 3 Display a prompt Read 3 into N Sum := 0; 0 Initialize Sum FOR i IN 1 .. N LOOP 1 3 0 Initialize i to 1 Sum := Sum + i 1 Add 1 to Sum Increment and test i 2 3 1 2<=3 is true Sum := Sum + i 3 Add 2 to Sum Increment and test i 3 3 3 3<=3 is true Sum := Sum + i 6 Add 3 to Sum Increment and test i ? 3 6 Exit Loop Ada.Text_IO.Put(Item=>"The Sum is"); Display message Ada.Text_IO.Put(Item=>Sum.Width=>1); 6 Display 6

TESTING

Did the test results agree with your predictions?


Previous | Next | Table of Contents | Index | Program List | Copyright

Copyright © 1996 by Addison-Wesley Publishing Company, Inc.