Loops are often used to repeat a sequence of steps according to some numbered pattern, instead of doing so until a special condition is realized as in the last section. There may be a predetermined number of times to repeat the loop, or the number of times may depend on the values of one or more program variables.
A repetition of a sequence of program steps according to some numbered pattern is called a counting loop or an iteration.
A couple of typical situations follow:
count := 1;
WHILE count <= 10
DO
Statement Sequence;
count := count + 1;
END;
or
count := 1;
WHILE count <= 10
DO
Statement Sequence;
count := count * 2;
END;
The first loop executes for count equal to 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10. At the end of the tenth time through, count is 11 and the boolean expression controlling re-entry to the loop is now false, so control passes to the next statement following the END of the WHILE loop. The second loop executes with count set to 1, 2, 4, and 8, and then terminates with count equalling 16. The following simple program, presented without any commentary, illustrates a counting loop. It prints a table of ten consecutive integers together with their squares and cubes.
MODULE SquareCube;
(* Written by R.J. Sutcliffe *)
(* to illustrate the use of counting loops *)
(* using P1 Modula-2 for the Macintosh computer *)
(* last revision 1993 02 16 *)
FROM STextIO IMPORT
WriteString, WriteLn, ReadChar, SkipLine;
FROM SWholeIO IMPORT
ReadInt, WriteInt;
CONST
numToDo = 10;
VAR
curNumber, finish : INTEGER;
answer, cr : CHAR;
again : BOOLEAN;
BEGIN
(* write information *)
WriteString ("SquareCube was written by R.J. Sutcliffe");
WriteLn;
WriteString ("as an example in the use of counting loops.");
WriteLn;
WriteLn;
WriteString ("This program computes the squares and cubes ");
WriteLn;
WriteString (" of ten integers starting with ");
WriteString ("the one you provide. ");
WriteLn;
WriteLn;
REPEAT
(* Gather the information from the user *)
WriteString ("Please enter the first integer ==> ");
ReadInt (curNumber);
SkipLine;
finish := curNumber + numToDo;
(* print headings for the table *)
WriteString ("Number Square Cube ");
WriteLn;
WHILE curNumber <= finish
DO
WriteInt (curNumber, 6);
WriteInt (curNumber * curNumber, 10);
WriteInt (curNumber * curNumber * curNumber, 16);
WriteLn;
curNumber := curNumber + 1;
END;
(* see if it should be done again *)
WriteLn;
WriteString ( "Do another sequence? Y or N ==> ");
ReadChar (answer);
again := (answer = "Y") OR (answer = "y");
SkipLine;
WriteLn;
UNTIL NOT again;
END SquareCube.
NOTE: In some non-standard versions of Modula-2, the LONGINT type may be needed to hold larger numbers than can be coped with by the INTEGER type. Where both exist, the exact limitations of the two must be determined from the individual system manuals.
Here is a successful run:
SquareCube was written by R.J. Sutcliffe
as an example in the use of counting loops.
This program computes the squares and cubes
of ten integers starting with the one you provide.
Please enter the first integer ==> 45
Number Square Cube
45 2025 91125
46 2116 97336
47 2209 103823
48 2304 110592
49 2401 117649
50 2500 125000
51 2601 132651
52 2704 140608
53 2809 148877
54 2916 157464
55 3025 166375
Do another sequence? Y or N ==> y
Please enter the first integer ==> 1000
Number Square Cube
1000 1000000 1000000000
1001 1002001 1003003001
1002 1004004 1006012008
1003 1006009 1009027027
1004 1008016 1012048064
1005 1010025 1015075125
1006 1012036 1018108216
1007 1014049 1021147343
1008 1016064 1024192512
1009 1018081 1027243729
1010 1020100 1030301000
Do another sequence? Y or N ==> n
On occasion, one might want to terminate a counting loop prematurely, because some condition has occurred that requires it. Such code could look something like:
count := start;
WHILE count <= finish
DO
Statement Sequence;
IF interesting condition
THEN
count := finish + 1; (* value to guarantee exit from loop *)
ELSE
count := count + increment; (* continue processing *)
END; (* if *)
END; (* while *)
Setting the loop counter to an exit value forces the loop to terminate when the second END is reached. This sort of construction can be used to avoid errors in a program or as a possible evasive action following a check on the validity of input data. This example also illustrates that the number of times a loop will execute may not be known when the program is written. Suppose, for instance, that start were greater than finish for some reason. The loop would not execute at all, and control would pass to the next statement.