Just like an IF-THEN-ELSE-END IF can contain another IF-THEN-ELSE-END IF (see nested IF for the details), a DO-loop can contain other DO-loops in its body. The body of the contained DO-loop, usually referred to as the nested DO-loop, must be completely inside the containing DO-loop. Note further that an EXIT statement only brings the control out of the inner-most DO-loop that contains the EXIT statement.
Suppose we have the following nested DO loops:
DO
statements-1
DO
statement-2
END DO
statement-3
END DO
Each iteration of the outer DO starts with statements-1.
When the control reaches the inner DO, statements-2 is
executed until some condition of the inner DO brings the control
out of it. Then, statements-3 is executed and this completes one
iteration. Any EXIT in the inner DO brings the control out of
the inner DO to the first statement in statement-3.
The following are a few simple examples:
INTEGER :: i, j
DO i = 1, 9
DO j = 1, 9
WRITE(*,*) i*j
END DO
END DO
Once this is done, the value of i is advanced to the next
one, and the inner loop will iterate 9 times again displaying
the product of the new i and 1, 2, 3,4 ..., 9.
The net effect is a multiplication table. For i=1, the value if 1*1, 1*2, 1*3, ..., 1*9 are displayed; for i=2, the displayed values are 2*1, 2*2, 2*3, ..., 2*9; ...; for i=9, the displayed values are 9*1, 9*2, 9*3, ..., 9*9.
INTEGER :: u, v
INTEGER :: a, b, c
DO u = 2, 5
DO v = 1, u-1
a = 2*u*v
b = u*u - v*v
c = u*u + v*v
WRITE(*,*) a, b, c
END DO
END DO
The above discussion can be summarized in the following table:
| u | Values for v | |||
| 2 | 1 | |
|
|
3 | 1 | 2 | |
|
4 | 1 | 2 | 3 | |
5 | 1 | 2 | 3 | 4 |
For each pair of u and v, the inner loop computes a, b and c. Thus, it will generate the following result (please verify it):
| u | v | a | b | c |
| 2 | 1 | 4 | 3 | 5 |
| 3 | 1 | 6 | 8 | 10 |
| 2 | 12 | 5 | 13 | |
| 4 | 1 | 8 | 15 | 17 |
| 2 | 16 | 12 | 20 | |
| 3 | 24 | 7 | 25 | |
| 5 | 1 | 10 | 24 | 26 |
| 2 | 20 | 21 | 29 | |
| 3 | 30 | 16 | 34 | |
| 4 | 40 | 9 | 41 |
INTEGER :: i, j, Sum
DO i = 1, 10
Sum = 0
DO j = 1, i
Sum = Sum + j
END DO
WRITE(*,*) Sum
END DO
REAL :: Start = 0.1, End = 1.0, Step = 0.1
REAL :: X, NewX, Value
Value = Start
DO
IF (Value > End) EXIT
X = Value
DO
NewX = 0.5*(X + Value/X)
IF (ABS(X - NewX) < 0.00001) EXIT
X = NewX
EBD DO
WRITE(*,*) 'The square root of ', Value, ' is ', NewX
Value = Value + Step
END DO
Newton's method is taken directly from the programming
example, where X is the current guess, NewX is the
new guess, and Value is the number for square root
computation. The EXIT statement brings the execution
of the inner DO to the WRITE statement.
If the inner loop is removed, we have the outer loop as follows:
It is clear that the value of Value starts with 0.1 and have a step size 0.1 until 1.0. Thus, the values of Value are 0.1, 0.2, 0.3, ..., 0.9 and 1.0. For each value of Value, the inner loop computes the square root of Value. The EXIT statement in the outer loop brings the control out of the outer loop.REAL :: Start = 0.1, End = 1.0, Step = 0.1 REAL :: X, NewX, Value Value = Start DO IF (Value > End) EXIT ! ! the inner loop computes the result in NewX ! WRITE(*,*) 'The square root of ', Value, ' is ', NewX Value = Value + Step END DO