In this section, we examine nested loops. Nested loops consist of an outer loop with one or more inner loops. Each time the outer loop is repeated, the inner loops are reentered, their loop control parameters are reevaluated, and all required iterations are performed.
Example 5.5
Program
5.8 shows a program with two nested FOR
loops. The outer loop
is repeated three times (for OuterCounter
equals 1, 2, and 3).
Each time the outer loop is repeated, the statements
Ada.Text_IO.Put (Item => "OUTER"); Ada.Integer_Text_IO.Put (Item => OuterCounter, Width => 7); Ada.Text_IO.New_Line;
display
the string "OUTER"
and the value of OuterCounter
(the
outer loop counter). Next, the inner loop is entered, and its loop counter
InnerCounter
is reset to 1. The number of times the inner loop is
repeated depends on the current value of OuterCounter
. Each time
the inner loop is repeated, the statements
Ada.Text_IO.Put (Item => "INNER"); Ada.Integer_Text_IO.Put (Item => InnerCounter, Width => 10); Ada.Text_IO.New_Line;
display
the string "INNER"
and the value of InnerCounter
(the
inner loop counter).
Program 5.8
FOR
Loops
WITH Ada.Text_IO; WITH Ada.Integer_Text_IO; PROCEDURE Nested_Loops IS ------------------------------------------------------------------------ --| Illustrates a pair of nested FOR loops. --| Author: Michael B. Feldman, The George Washington University --| Last Modified: July 1995 ------------------------------------------------------------------------ BEGIN -- Nested_Loops Ada.Text_IO.Put(Item => " OuterCounter InnerCounter"); Ada.Text_IO.New_Line; FOR OuterCounter IN 1 .. 3 LOOP Ada.Text_IO.Put(Item => "OUTER"); Ada.Integer_Text_IO.Put(Item => OuterCounter, Width => 10); Ada.Text_IO.New_Line; FOR InnerCounter IN 1 .. OuterCounter LOOP Ada.Text_IO.Put(Item => " INNER"); Ada.Integer_Text_IO.Put(Item => InnerCounter, Width => 22); Ada.Text_IO.New_Line; END LOOP; END LOOP; END Nested_Loops;Sample Run
OuterCounter InnerCounter OUTER 1 INNER 1 OUTER 2 INNER 1 INNER 2 OUTER 3 INNER 1 INNER 2 INNER 3
In
Program 5.8, the outer loop counter
OuterCounter
is used as the
limit expression that determines the number of repetitions of the inner loop.
This is perfectly valid. It is also valid to use the same variable name as the
loop counter of both an outer and an inner FOR
loop in the same
nest. This is strongly discouraged, however, because it causes the compiler to
create two "nested" variables with the same name. Although this is not a
problem for the compiler, it certainly is a source of confusion for the human
reader of the program!
Example 5.6
Program
5.9 prints an isosceles triangle. The program contains an outer loop (loop
counter Row
) and two inner loops. Each time the outer loop is
repeated, two inner loops are executed. The first inner loop prints the leading
blank spaces; the second inner loop prints one or more asterisks.
The outer loop is repeated five times; the number of repetitions performed by
the inner loops is based on the value of Row
. Table 5.3 lists the
inner loop control parameters for each value of Row
. As the table
shows, four blanks and one asterisk are printed when Row
is 1,
three blanks and three asterisks are printed when Row
is 2, and so
on. When Row
is 5, the first inner loop is skipped and nine (2 × 5
- 1) asterisks are printed.
Program 5.9
WITH Ada.Text_IO; PROCEDURE Triangle IS ------------------------------------------------------------------------ --| Draws an isosceles triangle --| Author: Michael B. Feldman, The George Washington University --| Last Modified: July 1995 ------------------------------------------------------------------------ NumLines: CONSTANT Integer := 5; Blank : CONSTANT Character := ' '; Star : CONSTANT Character := '*'; BEGIN -- Triangle FOR Row IN 1 .. NumLines LOOP -- draw each row FOR LeadBlanks IN REVERSE 1 .. NumLines - Row LOOP Ada.Text_IO.Put(Item => Blank); -- display leading blanks END LOOP; FOR CountStars IN 1 .. (2*Row) - 1 LOOP Ada.Text_IO.Put(Item => Star); -- display asterisks END LOOP; Ada.Text_IO.New_Line; -- terminate row END LOOP; END Triangle;Sample Run
* *** ***** ******* *********
Table
5.3
Trace of Inner Loop Parameters in Triangle
Row LeadBlanks CountStars Effect 1 REVERSE 1..4 1..1 Displays 4 blanks and 1 star 2 REVERSE 1..3 1..3 Displays 3 blanks and 3 stars 3 REVERSE 1..2 1..5 Displays 2 blanks and 5 stars 4 REVERSE 1..1 1..7 Displays 1 blank and 7 stars 5 REVERSE 1..0 1..9 Displays 0 blanks and 9 stars
a.
FOR I IN 1..N LOOP FOR J IN 1..I LOOP Ada.Text_IO.Put(Item => '*'); END LOOP; Ada.Text_IO.New_Line; END LOOP;
b.
FOR I IN 1..N LOOP FOR J IN 1..M LOOP Ada.Text_IO.Put(Item => '*'); END LOOP; Ada.Text_IO.New_Line; END LOOP;
FOR I IN 1..2 LOOP Ada.Text_IO.Put(Item=>"Outer"); Ada.Integer_Text_IO.Put(Item=>I, Width=>5); FOR J IN 1..3 LOOP Ada.Text_IO.Put(Item=>"Inner "); Ada.Integer_Text_IO.Put(Item=>I, Width=>3); Ada.Integer_Text_IO.Put(Item=>J, Width=>3); END LOOP; FOR K IN REVERSE 1..2 LOOP Ada.Text_IO.Put(Item=>"Inner "); Ada.Integer_Text_IO.Put(Item=>I, Width=>3); Ada.Integer_Text_IO.Put(Item=>K, Width=>3); END LOOP; END LOOP;
1 1 2 1 2 3 1 2 3 4 1 2 3 1 2 1
Copyright © 1996 by Addison-Wesley Publishing Company, Inc.