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.

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 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

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 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!!)

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.

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.