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;
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.