DO loop_variable = begval,endval,stepStatements internal to the loop follow this initial line and the entire loop is completed by the statement:
END DO
loop_variable can be any
integer variable and is the counter for the loop. This
variable can be used within the loop, but no attempt should be
made to try to change its value. Some compilers will give an
error if this variable is used on the left of an assignment
statement within the loop. Officially, the loop variable will be
undefined when the loop is completed.
begval, endval, step are integer constants or variables which correspond, respectively, to the beginning value of the loop variable, the ending value, and the step size.
If the step constant (or variable) is omitted (with its preceding comma), the step size is assumed to be 1.
Officially the number of iterations performed by the DO loop is given by the formula:
maximum((endval - begval + step)/step, 0)One consequence of this formula is that (with a positive step value) if the ending value is less than the beginning value, the body of the loop will not be executed at all.
DO I=1,10
SQUARE = I*I
WRITE(6,*) I, SQUARE
END DO
One may label the DO-loop with an
alphanumeric identifier
that precedes the keyword DO and is followed by a single colon.
(Such labels are useful when dealing with nested loops. See comments
on the CYCLE and EXIT statements below in section 6.11.2.1.)
If the initial DO statement is labeled, the END DO
statement may have the same label appended as well. For example,
LOOP1 : DO I=1,10
SQUARE = I*I
WRITE(6,*) I, SQUARE
END DO LOOP1
n CONTINUE
where n is any positive integer with a maximum of five digits.
DO n loop_variable = begval,endval,stepFORTRAN-77 also allows:
DO n , loop_variable = begval,endval,stepThe number n that follows the keyword DO is the statement number of the last statement to be executed in the loop and must be an integer constant. This last statement must be an executable statement, and thus, it cannot be a FORMAT or an END (among others). Although this final statement (in the FORTRAN-77 version of a DO loop) may be any executable statement, contemporary programming style suggests that such DO loops should end only with a CONTINUE statement.
FORTRAN-77 permitted the optional presence of a comma between the statement number n and the loop variable. Using this comma can avoid errors of the type mentioned below in section 6.8.
Because of the difficulty in determining exactly how many times a loop is performed in real arithmetic, the use of real numbers for the loop counter was considered problematic and, thus, Fortran-95/2003 no longer supports real variables as loop counters. Therefore, future compilers may give an error message if the loop counter is of type real.
In early versions of Fortran, the DO loop counter variable test is performed at the end of the loop. As a result, even if the beginning value and ending value are inconsistent (e.g. DO 10 I=5,1,2), the loop is executed at least once.
In Fortran-90/95/2003 and FORTRAN-77, one can interpret the test as being performed at the beginning of the loop. Thus, depending on whether there is a positive step size or not, the loop may or may not be done. For example, DO 10 I=5,1,2 would not be done at all, but DO 10 I=5,1,-2 would be done 3 times (with the loop variable I having the values of 5, 3, and 1).
NOTE: Many Fortran compilers provide options which allow users to determine whether they wish DO loops in their programs to run according to early FORTRAN or Fortran-90/95/2003 rules, thereby making old programs that run on new compilers give the same results. Only a relatively few programs would be affected by the change of rules.
A = 0.0 DO 10 I=1,20 A=A+1.0 10 CONTINUEThis piece of code would perform the assignment statement within the loop 20 times, adding 1.0 to the previous value of A each time. Thus, at the end of this piece of code, the variable A would have the value of 20.0.
To explain how a substitution of a period for a comma could cause a problem consider the following code segment. Suppose one omits the step size and changes the comma to a period in a DO loop statement. In other words, instead of writing
DO 10 I = 1, 10suppose one writes,
DO 10 I = 1. 10The first statement is a valid DO loop header. To analyze the second statement, recall (1) that, in the older Fixed Source Form, blanks are ignored, (2) that variables do not have to be declared before use in Fortran, and (3) that the data type of an undeclared variable is determined (by default) according to the first letter. If we re-write the second statement after omitting blanks, we get
DO10I=1.10This statement now can be seen to be an assignment statement (rather than a DO loop header), giving the (default typed) real variable DO10I the value of 1.10. Thus, instead of the interior statements of what was thought to be a loop being performed 10 times, they would be done only once, and could lead to answers drastically different than what was expected.
For example, the following example, using FORTRAN-77 style DO-loops, would give a compiler error.
DO 10 I=1,10 DO 20 J=1,20 ... 10 CONTINUE 20 CONTINUE(One cannot have the beginnings and endings of loops overlap each other.)
On the other hand, the following is perfectly good Fortran.
DO 110 I=1,10 DO 120 J=1,20 ... 120 CONTINUE 110 CONTINUENote that in this second case, the interior loop (DO 120 J ...) begins and ends completely within the range of the outer loop.
Note also the effect of this construction. For each pass of the outer loop (the "DO 110 I" loop), the inner loop is completely executed (all 20 times). Therefore, the statements interior to the inner loop are (in this case) executed a total of 200 (10×20) times.
PROGRAM TEST ! ! PROGRAM TO CREATE A CONVERSION ! CHART CONVERTING MILES TO KILOMETERS ! FROM 5 MILES TO 60 MILES ! ! VARIABLE DECLARATIONS ! INTEGER NUM REAL MILES,KILOS,EIGHT5 ! ! INITIALIZATION AND HEADER ! EIGHT5=8.0/5.0 WRITE(6,100) 100 FORMAT(7X,'Miles',3X,'Kilometers') ! ! LOOP TO CONVERT MILES TO KILOMETERS ! DO NUM=5,60,5 MILES=NUM KILOS=MILES*EIGHT5 WRITE(6,101) MILES,KILOS 101 FORMAT(1X,2F10.1) END DO STOP END
PROGRAM TEST C C PROGRAM TO CREATE A CONVERSION C CHART CONVERTING MILES TO KILOMETERS C FROM 5 MILES TO 60 MILES C C VARIABLE DECLARATIONS C INTEGER NUM REAL MILES,KILOS,EIGHT5 C C INITIALIZATION AND HEADER C EIGHT5=8.0/5.0 WRITE(6,100) 100 FORMAT(7X,'Miles',3X,'Kilometers') C C LOOP TO CONVERT MILES TO KILOMETERS C DO 20 NUM=5,60,5 MILES=NUM KILOS=MILES*EIGHT5 WRITE(6,101) MILES,KILOS 101 FORMAT(1X,2F10.1) 20 CONTINUE STOP END
DO WHILE ( logical condition )
...
END DO
As long as the condition is true, the loop will continue its operation,
but when the condition turns false, the loop is exited. Since this
loop can be coded by using the infinite DO-loop construction
described in the next subsection,
the DO WHILE statement has been designated as
obsolete by some authors and its use is discouraged.
DO
...
END DO
forces an infinite loop. This is not too useful in itself, but can be
helpful if used with an EXIT clause within an interior IF
statement.
IF ( .NOT. (TOT <= 100) ) EXIT
When the condition turn .TRUE., this statement
would end the looping action and continue the program with the statement
after the END DO. For example, the following construction
would imitate a while loop:
DO ! while TOT <= 100
IF ( .NOT. (TOT <= 100) ) EXIT
loop statements go here
END DO
The following example would imitate a Pascal repeat ... until
loop:
DO ! repeat
loop statements go here
IF (TOT > 100) ) EXIT ! until tot > 100
END DO
We can use CYCLE in a similar way to skip the rest of the statements in the loop but continue the loop process itself. Any statement between the CYCLE statement and the END DO statement is ignored for that iteration only and the next iteration of the DO-loop begins. For example,
IF ((5 < I) .AND. (I < 9)) CYCLE
would cause the loop statements following this line
(until the END DO) to be skipped
when I had the values of 6, 7, or 8, but not when I
has values less than 6 or greater than 9.
If two or more DO-loops are nested, any EXIT or CYCLE statement refers to the innermost loop of which it is a member. To CYCLE or EXIT out of another enclosing loop, one should label the appropriate loop and append to the CYCLE or EXIT statements the label that corresponds to the appropriate loop. For example, the following statement makes it explicit which loop is being exited:
IF (TOT > 10) EXIT LOOP1
The DO loop presupposes sequential execution of the statements in the body of the loop. In other words, it presupposes that one iteration will be completed before the loop counter is changed and the next iteration is begun.
In contrast, the FORALL loop has no such presupposition. It assumes that the body of the loop will be performed for all values of the index variable, but leaves the order undetermined. This means that such loops may be optimized for use on parallel machines in which certain iterations may be done simultaneously with others.
The syntax for the counter is slightly different than for the counted DO as shown in the following example:
FORALL (i=1:n)
a(i) = 2*i
END FORALL
As in a DO loop, a stride may be added after the
upper limit, e.g., i = 1:20:2 if it is desired that
the loop counter go from 1 to 20 by 2's.
An additional feature of the FORALL loop is that the condition within parentheses may include multiple index specifiers separated by commas, for example:
FORALL (i=1:12, j=1:12)
b(i,j) = i*j
END FORALL
One may also include a "mask" as the final element between the
parentheses (cf. The WHERE Construct,
section 8.12),
which is a logical condition
tested before each execution of the body of the loop.
For example, if one wanted to create a new two-dimensional array in
which every element were the reciprocal of elements in another array
(avoiding division by 0), then that could be accomplied by the
following code:
FORALL (i=1:12, j=1:12, b(i,j) /= 0.0)
b_recip(i,j) = 1/b(i,j)
END FORALL
DO
READ(20,101,END=200) A,B,C
...
END DO
200 CONTINUE
This would read in data into variables A, B and C until
the end of the file were reached and then jump out of the loop to
statement labeled 200.
The other option is to use the IOSTAT ("input output status") option within a READ statement. In this case, one first needs to declare an integer variable that will store the "status value" of the input file after a READ. On most systems, if the value becomes negative (usually -1), the READ statement has attempted to read past the end-of-file. As an example, we have:
INTEGER IO
...
DO
READ(20,100,IOSTAT=IO) A,B
IF (IO < 0 ) EXIT
...
END DO
Although the second option (using IOSTAT)
may seem more complicated than the first (using END=), it
has the advantage of avoiding an implicit GO TO statement
and the need for a corresponding statement label. Thus, from the
point of view of contemporary programming style, using IOSTAT
is to be preferred.
More details can be found in fuller manuals on FORTRAN-77 or Fortran-90/95/2003.
This page is maintained by Dennis C. Smolarski, S.J.
dsmolarski@math.scu.edu
© Copyright 1998-2005
Dennis C. Smolarski, S.J., All rights reserved.
Last changed: 27 June 2005.