Loops
Much computing is repetitive work. Evaluate an expression many times with different values. Read lines of a file. Update a large number of variables. To accomplish this, we use loops.
DO Loop
DO
is the equivalent of for
in languages like C/C++.
DO executes a fixed number of iterations unless explicitly terminated.
DO can iterate only over integer sequences. Some compilers support real indices as an extension, but they should be avoided.
INTEGER :: L, U, S
INTEGER :: I
DO I=L,U,S
code
END DO
I
is the loop variable,
L
is the lower bound,
U
is the upper bound, and
S
is the stride. It is equal to 1 if not present.
The stride can be negative, in which case L
must be greater than U
.
Fortran always starts at the first bound and includes the second bound.
QUIZ
The standard requires that loop variables be integers. How would I implement loop variables that are real?
How might real loop variables be a problem?
Implied DO
The implied do is used in a few circumstances, specifically input/output and array construction.
(var(iterator),iterator=lbound,ubound,s)
The parentheses are required.
Example
(a(i),i=1,20)
Implied do loops can be nested.
((r(i,j),j=1,M),i=1,N)
WHILE Loops
Whereas DO
loops execute a particular number of iterations, WHILE
loops iterate based on the truth or falsity of an expression. The WHILE
continues as long as the expression is .true.
and terminates when it becomes .false.
. It is up to the programmer to be sure to add statements to ensure that the expression eventually evaluates to .false.
so the loop will end.
DO WHILE (<logical expression>)
statement
statement
statement somewhere to check expression
END DO
Example
program demo
implicit none
integer :: x, y, z
x=-20
y=-10
do while (x<0 .and. y<0)
x=10-y
y=y+1
z=0
enddo
z=1
print *, x, y, z
end program
Exiting Early and Skipping Statements
The EXIT
statement leaves the loop immediately.
EXIT
is able to break out of only the loop level in which it appears. It cannot break from an inner loop all the way out of a nested set of loops. This is a case where goto
is better than the alternatives. EXIT
is equivalent to
break
of several other languages.
CYCLE
skips the rest of loop and goes to the next iteration. It is equivalent to continue
of other languages. Like EXIT
, it applies only to the loop level in which it is located.
x=1.
do while (x>0.0)
x=x+1.
if (x>=10000.0) exit
if (x<100.0) cycle
x=x+20.0
enddo
Repeat-Until
The standard DO
and WHILE
loops test at the top. That is, upon entry to the loop, the termination condition is evaluated. If it is false, the statements of the loop are executed. Otherwise the loop is exited.
With the ability to break out of the loop at will, we can change this pattern.
One particularly common pattern is called repeat until
.
do
statement
statement
if (<logical expression>) exit
end do
One major reason for repeat-until is that a standard while
loop may not be entered if the condition is initially false, whereas a repeat-until will always be executed at least once.
Example Reading a file of unknown length. This is not how we usually read a file, since most of the time the length is known, but it is possible to construct a loop to read a file whose length may vary for different runs.
nlines=0
do
read(unit=iunit, end=10) var
nlines=nlines+1
enddo
10 continue
Exercises
1 Loop from 0 to 20 by increments of 2. Make sure that 20 is included. Print the loop variable at each iteration. 2 Start a variable n at 1. As long as n is less than 121, do the following:
- If n is even, add 3
- If n is odd, add 5
- Print n for each iteration. Why do you get the last value? 3 Set a real value x=0. Loop from 1 to L inclusive by 1.
- If the loop variable is less than M, add 11. to x.
- If x > w and x < z, skip the iteration.
- If x > 100., exit the loop.
- Print the final value of x.
- Experiment with different values for the variables. Start with L=50, M=25, w=9., z=13.
Example Solution
program looper
! Set up some loops
implicit none
integer :: i,n,L,M
real :: w,x,z
print *, "Part 1"
do i=0,20,2
print *, i
enddo
print *, "Part 2"
n=1
do while (n<121)
if (mod(n,2)==0) then
n=n+3
else
n=n+5
endif
print *, n
enddo
print *, "Part 3"
! Remember that case doesn't matter, but capital L doesn't look like the digit one
L=50
M=25
w=9.
z=13.
x=0.
do i=1,L
if (i<M) then
x=x+11
endif
if (x>w .and. x<z) cycle
if (x>100.) exit
enddo
print *, x
end program