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



Previous
Next