Part 6. Loop and branch instructions

(c) 2017 by Barton Paul Levenson



Suppose you had a homework assignment to find the area of ten circles. To write a program to do that, you could do the straightforward thing and repeat the same lines of code ten times.

Or you could use a loop. A "do loop" runs the same sequence of code a given number of times. Here's the circle program using a do loop:


! Program to find areas of several circles.
program circles
    implicit none
    integer, parameter :: d  = selected_real_kind(p = 15)
    real(d), parameter :: pi = 3.141592653589793d0

    real(d)       :: area, radius	! Of the circle.
    integer       :: i			! Loop counter.
    integer       :: N			! Number of circles.
    character(80) :: units		! Linear units used.

    write (*, 5)
 5  format('How many circles are there?  =>', $)
    read  (*, *) N

    do i = 1, N    
        write (*, 10)
10      format(//'What radius is the circle?   =>', $)
        read  (*, *) radius

        write (*, 20)
20      format('What units is that in?       =>', $)
        read  (*, *) units	

        area = pi * Radius ** 2

        write (*, 30) area, trim(units)
30      format('The area is ', f10.5, ' square ', a, '.')
    end do
end program circles


Note the convention of indenting the body of a loop to make it stand out from the rest of the program. Note also that the do loop uses an "index variable" or "loop counter," here called i. This i is first set to 1, the loop runs, then i is set to 2, and so on until it reaches N, at which point the loop runs one last time and quits.

The slashes ( / ) inside format 10 produce blank lines. They are equivalent to a "newline character" in C, C++ or Java.

The syntax of this "iterated do loop" is:


    do <counter> = start, end, increment
        statement(s)
    end do


The counter variable must be an integer, as must the start, end and increment values. The increment can be positive or negative. If left out, the default value is 1.

But suppose you didn't know in advance how many problems there were? Suppose computing circle areas was something you needed for your job, or for research you were doing, and the number of circles was too large to count easily? Then you could use a "simple do loop," which just cycles endlessly, until the user does something to stop it. Here's an example

write(*, *) 'Enter radii until you run out of problems.' write(*, *) 'Then enter a negative number to stop the loop.' do write (*, 10) 10 format(//, 'What radius is the circle? =>', $) read (*, *) radius if (radius <= 0d0) exit write (*, 20) 20 format('What units is that in? =>', $) read (*, *) units area = pi * radius ** 2 write (*, 30) area, trim(units) 30 format('The area is ', f10.5, ' square ', a, '.') end do


The line starting with the word if is, appropriately enough, an if-structure. The format is:


    if (logical condition) statement


where "logical condition" is some construction that is either true or false. Ours tests whether the value of radius is positive or not; if not, we leave the loop with the exit command.

The Fortran logical comparison operators are:


operatoralternative operatormeaning
>
.gt.
greater than
<
.lt.
less than
>=
.ge.
greater than or equal to
<=
.le.
less than or equal to
==
.eq.
equals
/=
.ne.
does not equal

Look carefully at that "==" for the logical equality operator. Make sure you distinguish it from the "=" used in assignment statements--because an assignment statement can sometimes be treated as if it produced a logical value! This can be a very subtle and difficult logic bug to track down. The equals sign ( = ) is for assignment. The equality sign ( == ) is for logical comparison. Strive mightily not to confuse them.

For more complex logical expressions, the operators .and., .or, and .not. are also available. And you can change precedence with parentheses.

Look again at the if structure in the last example of a loop. This "simple if structure" executes a statement if, and only if, the logical expression in parentheses evaluates to "true." To accommodate more than two alternatives, there also exists a "block if structure." In this, alternatives can be executed using the keywords elseif and else. Here's a short example program:


! fruit tests the "block if structure" in Fortran 95.
program fruit
    character(20) :: color		! Color of a fruit.

    write(*, *) 'What color?'
    read (*, *) color

    if (trim(color) == 'red') then
        write(*, *) 'Strawberry!'

    else if (trim(color) == 'yellow') then
        write(*, *) 'Banana!'

    else
        write(*, *) 'Some other fruit!'
    end if
end program fruit


Any number of else if clauses can be used, including none. The else clause is also optional. And, as opposed to the simple if structure, you can use if-end if to sandwich in any number of statements to run if the condition is true:

	
    if (trim(situation) == 'meltdown') then
        write(*, *) 'Core melting down!'
        call planeTicketPurchase
        call moveFunds('Bank of America', 'Swiss Bank')
    end if


If you have many alternatives, a compact way to set them up uses the case statement. This involves setting up a variable, the "selector," to choose among alternatives:


integer :: class

select case (class)
   case (1)
      write(*,*)  'Freshman'
   case (2)
      write(*,*)  'Sophomore'
   case (3)
      write(*,*)  'Junior'
   case (4)
      write(*,*)  'Senior'
   case default
      write(*,*)  'Never heard of that before.'
end select


Selectors can be nearly any type, including character string. case values must be constants, but they can include ranges or multiple values:


    case (5:10)

    case (1, 3, 5, 7, 9)






Page created:05/05/2017
Last modified:  05/05/2017
Author:BPL