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;
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
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 100The 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
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)
FOR counter IN 1..repetitions LOOP statement sequence END LOOP; FOR counter IN REVERSE 1..repetitions LOOP statement sequence END LOOP;
FOR I IN 1 .. HowMany LOOP Ada.Integer_Text_IO.Put (Item => I, Width => 5); Ada.Text_IO.New_Line; END LOOP;
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.
We can use a counting loop to accumulate the sum of a collection of data values as shown in the next problem.
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
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 325A 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?
Copyright © 1996 by Addison-Wesley Publishing Company, Inc.