3.7 Counting Loops

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.


Contents