Control structures alter the normal sequential flow of a statement execution. Loops allow the a block of statements to be executed repeatedly without actually writing them down numerous times.
A DO
loop allows a block of statements to be executed repeatedly.
DO label, loop-control-variable = initial-value, final-value, step-size statement1 statement2 … statementn label CONTINUE
The label is any number between 1 and 99999 which is attached to
the final statement in the DO
loop. This final statement
may be any executable statement but is usually a CONTINUE
statement. The CONTINUE
statement is just a dummy statement
traditionally used at the end of a loop.
The loop-control-variable may be a variable (but not an array
element) of type INTEGER
, REAL
or
DOUBLE PRECISION
.
The initial-value, final-value and step-size
control the number of iterations. They may be any expression that evaluates
to an INTEGER
, REAL
or
DOUBLE PRECISION
, but the step-size must be
nonzero. The step-size may be omitted entirely in which case it
is taken to be 1.
The number of iterations is fixed at the beginning of the
DO
loop according to the formula
iterations = MAX(0,INT((final-value - initial-value + step-size)/step-size)
so altering the values of the initial-value, final-value and step-size inside the loop will not affect the number of times the loop is executed. The loop-control-variable may be (and often is) used in statements within the loop but it may not be assigned a new value there.
It is possible for the number of iterations to be zero, in which case the
loop is not executed and control passes to the next executable statement
following the labelled statement delimiting the end of the DO
loop.
Upon encountering a DO
statement, the
loop-control-variable is assigned the initial-value.
When a DO
loop finishes normally, the
loop-control-variable contains the value of the last iteration
(which is not necessarily the final-value) plus the
step-size.
Adding up the numbers between 1 and 100 is simple with a
DO
loop. If the step-size is equal to 1,
then it may be omitted from the DO
statement.
SUM = 0 DO 10, I = 1,100 SUM = SUM + I 10 CONTINUE
The loop-control-variable I
has the value
101
when the loop exits.
Suppose we wish to print out only the multiples of 3 between 0 and 100. This can be accomplished by setting the initial-value to 0 and the step-size to 3.
DO 20, I = 0,100,3 WRITE(*,*)I 20 CONTINUE
Obviously, the number 100 itself is not a multiple of 3. We could have
used 99 as the final-value instead and it would have given the
same result. The loop-control-variable I
has the value
102
when the loop exits.
As with block IF
statements, control may pass out of the
loop (for instance, with a GO TO
statement) but it is illegal
to transfer into the middle of a DO
loop. If the loop is
exited prematurely, the loop-control-variable keeps the value
that it had at that point.
Be aware that rounding errors may cause unintended effects when a
non-INTEGER
variable is used as the
loop-control-variable. Also, the number of iterations may not be
what you expect if non-INTEGER
values are used as the
initial-value, final-value or step-size.
In each of the examples, the statement blocks are indented slightly from the left. This is not a requirement but makes the structure of the program much more immediately obvious, particularly when there is deep nesting of control structures.
Nesting DO
loops is common, particularly when
manipulating multi-dimensional arrays.
Consider this program fragment which performs matrix-vector multiplication:
DO 20, I = 1,M SUM = 0.0 DO 10, J = 1,N SUM = SUM + MATRIX(I,J)*VECTOR(J) 10 CONTINUE PRDCT(I) = SUM 20 CONTINUE
Note that the inner DO 10
loop is completely contained
within the body of the outer DO 20
loop. Indentation
helps distinguish the nesting occurring in the code.
It is also permissable to nest block IF
statements
within a DO
loop. Nesting is also possible with the
loop structures described below.
A DO
loop iterates a fixed number of times but sometimes it
is necessary to loop based on some kind of testable criterion which does not
depend on the number of iterations. One such loop is called a do-while loop
which iterates zero or more times. FORTRAN 77 does not have a formal
do-while loop structure but it is easy to construct one using IF
and GO TO
statements.
label IF (logical-expression) THEN statement block GO TO label END IF
10 IF (Z .GE. 0D0) THEN Z = Z - SQRT(Z) GO TO 10 END IF
The statement labelled 10
is a block IF
.
If the value stored in the variable Z
is non-negative, then
the statement block in the block IF
is executed. In
this case, the value of Z - SQRT(Z)
is calculated
and assigned to the variable Z
. Then the
unconditional GO TO
statement is encountered and control
is passed out of the body of block IF
and back to the
statement labelled with the number 10
which is the beginning
of the block IF
. This loop continues until the
logical expression Z .GE. 0D0
is
.FALSE.
at which time the loop is finished and control
passes on to the next executable statement past the END IF
.
A do-while loop tests at the beginning of the loop. If the criterion is not satisfied, then the program does not enter the loop. Thus it is possible for the loop to be skipped completely.
Another type of loop is the repeat-until loop. This loop iterates one or
more times. Unlike the do-while loop, the repeat-until loop tests at the
bottom of the loop so it always executes at least once. Again,
FORTRAN 77 does not have a formal repeat-until loop but it is easy to
construct one using IF
and GO TO
statements.
label CONTINUE statement block IF (logical-expression) GO TO label
10 CONTINUE WRITE(*,*)'Enter a value 1-12 for the month' READ(*,*)MONTH IF (MONTH .LT. 1 .OR. MONTH .GT. 12) GO TO 10
The statement labelled 10
is a CONTINUE
statement
which is often used at the beginning or end of a loop structure. This
program fragment executes the CONTINUE
statement (which does
nothing) and then prints out the statement
Enter a value 1-12 for the month
.
The program then reads in a value from the standard input device and stores
it in the variable MONTH
. At this point MONTH
is
tested to see if it is between the values of 1 and 12 inclusive. If it is,
then control passes to the next executable statement, but if it isn't, then
the GO TO 10
statement is executed and the program
returns to the CONTINUE
statement. The program then goes
through the WRITE
and READ
statements again and
tests the new value of MONTH
. The program will not break out
of this loop until MONTH
has a legal value.