Section 3: IF Statements and Subroutines

The IF Construction

So far, the only control we have been able to exercise over the flow of a program is the ability to make it loop a specified number of times. Now we will consider what is possibly the most important construction available in a programming language: the IF construction.

The IF construction is important because it allows the program to make decisions. There are two forms: the single IF statement, and the block-IF construction.

IF Statements.

The IF statement takes the form: if ( condition ) action. What this means is that, if the condition in brackets is met, then the specified action is taken. The action is any single Fortran statement. The following piece of code illustrates the most common types of condition which may be used. A simple print statement is used as the action:

      integer a,b,c,d
c
      a = 1
      b = 2
      c = 3
      d = 4
c
      if (a.eq.b) print *, 'a = b'
      if (a.ne.b) print *, 'a not equal to b'
      if (a.gt.b) print *, 'a is greater than b'
      if (a.lt.b) print *, 'a is less than b'
      if (a.ge.b) print *, 'a is greater than OR equal to b'
      if (a.le.b) print *, 'a is less than OR equal to b'
c
      if ( (a.eq.b) .and. (c.eq.d) ) print *, 'a = b AND c = d'
      if ( (a.eq.b) .or. (c.eq.d) ) print *, 'either a = b, OR c = d'
      if ( .not. (a.eq.b) ) print *, 'a not equal b'
c

It should be clear what each of the above statements implies.

The Block-IF Construction

The block-IF construction is more sophisticated than the IF statement, allowing blocks of statements to be controlled by decision making conditions. The general format is as follows:

      integer a, b, c, d
c
      a = 1
      b = 2
      c = 3
      d = 4
c
      if (a.eq.b) then
c
c.......Several lines of code here.
c
        print *, 'a = b'
        print *, 'hello'
c
      else if (a.eq.c) then
c
c.......Several more lines of code here.c
c
        print *, 'a = c'
        print *, 'hello'
c
      else if (a.eq.d) then
        print *, 'a = d'
        print *, 'hello'
      else
        print *, 'a not equal to b, c or d'
      endif

This is a complicated example. In fact, the else statements are optional, and you may use as many of them as you like. The important thing to note is the use of the endif statement which is obligatory. In its simplest form, the block-IF would look something like this:

      integer a, b
c
      a = 1
      b = 2
c
      if (a.eq.b) then
c
c.......Several lines of code here.
c
        print *, 'a = b'
        print *, 'hello'
c
      endif

It is also possible to nest block-IF's as follows:

      integer a, b, c, d
c
      a = 1
      b = 2
      c = 3
      d = 4
c
      if (a.eq.b) then
        if (c.eq.d) then
          print *, 'a = b and c = d'
          print *, 'hello'
        endif
      endif

Exercise 3(a) - Modified Cartesian - Spherical polar convertor: Part 1

Using your program from Exercise 2 as a starting point, write a program which will convert Cartesian coordinates to spherical polar coordinates and which will convert spherical polar coordinates to Cartesian coordinates. Give the person the choice of which conversion to perform by using the the block-IF construct. Output your answers to the screen. Output and input q and f, the angular parts of the spherical polar coordinates, in degrees.
Remember: The default units for sine and cosine functions are radians.

CHECK: Do your answers agree with the following:

(r,q,f) = (5,45,60)

after conversion gives

(x,y,z) = (1.768,3.062,3.536)

q and f are in degrees and answers have been rounded to three decimal places.


The GOTO Statement

The goto statement allows a transfer of control to another part of the program. It is frowned upon by many programmers because it allows programs to become extremely complicated. However, it can be useful if used sparingly, so we shall give an example here:

      integer a
c
10    print *, 'Here we go again.'
c
c.....Lots of lines of code.
c
      print *, 'Enter 1 to go around again:'
      read *, a
      if (a.eq.1) goto 10
c
      end

Note the use of a statement label to indicate the destination of the jump. The above is a handy way of repeating a program without having to restart it.

NOTE: DO NOT USE GOTO STATEMENTS!!!
(unless absolutely necessary, which is almost never!!)

Subroutines

It is often useful to write subroutines, usually to carry out a repetitive procedure which you might need at several points in a program, or in several programs. Subroutines may either be contained in the same file as the main program, or in separate files. In the latter case, the files containing all of the subroutines would have to be specified when linking the program. For simplicity, we will assume that all of our subroutines are contained in the same file. The following example illustrates their use:

      program moduli
c
      implicit none
      double precision x1, y1, r1
      double precision x2, y2, r2
      double precision x3, y3, r3
c
      x1 = 1.0d0
      y1 = 2.0d0
      call find_modulus ( x1, y1, r1)
      print *,'The modulus of the vector is: ',r1
c
      x2 = 3.0d0
      y2 = 4.0d0
      call find_modulus ( x2, y2, r2)
      print *,'The modulus of the vector is: ',r2
c
      x3 = 5.0d0
      y3 = 6.0d0
      call find_modulus ( x3, y3, r3)
      print *,'The modulus of the vector is: ',r3
c
      end  ! This is the end of the MAIN program.


      subroutine find_modulus (a, b, c)  !  The start of the subroutine...
c
c.....Subroutine to calculate the modulus of a vector, whose components are 
c     'a' and 'b'.  The value is returned in 'c'.
c
      implicit none
      double precision a, b, c
c
      c = sqrt ( a*a + b*b )
c
      return  ! This transfers control back to the main program.
      end     ! This is the end of the subroutine.

In this example, the subroutine find_modulus is called several times to calculate the moduli of vectors (x1,y1) (x2,y2) and (x3,y3).

The most important thing to notice when using a subroutine is that the argument lists in the call statement must match the subroutine definition in both number and variable type. For example, in the above case, there are 3 arguments, and they are all double precision. The program would fail, and possibly crash, if more than 3 argument were given, or if integers were used where double precision variables were expected.

The other thing to notice is that the variables in the subroutine definition (a, b and c) are local to the subroutine. In other words, you could use the same variable names in the main program, and their values would be independent of anything that occurred in the subroutine.


Exercise 3(b) - Modified Cartesian - Spherical polar convertor: Part 2

Modify your program from Exercise 3(a) so that the Cartesian coordinates to spherical polar coordinates and the spherical polar coordinates to Cartesian coordinates sections of your program are contained in two individual subroutines.


Next: Section 4: Parameter Statements and User Defined Functions

Previous: Section 2: Arrays and Intrinsic Functions


Return to Dr. Alex Brown's Teaching

This page maintained by alex.brown@ualberta.ca of the Department of Chemistry, University of Alberta

Last updated August 8, 2003.