Fortran Subprograms

Until now, the example programs presented contained only a main program. The main program actually is a subprogram. The only thing that distinguishes the main program from other subprograms is the fact that it is the first subprogram to run when a new process is created. For this reason, the main program is also called the entry point.

Within each subprogram there are variable definitions and statements, exactly like we have seen in our main programs.

Fortran offers two kinds of subprograms, which are implemented almost exactly the same way. The only difference between them is in how they are invoked, or called.

When a subprogram is called, the program "jumps" to the subprogram, runs it, and then returns to where the subprogram was called and continues executing the caller.

A function is a subprogram that is invoked by using it in an expression. Since a function call is part of an expression, it must return a value, which is used in the expression.

The main program calls other subprograms, which may in turn call other subprograms, and so on.

The call tree shows which subprograms call other subprograms. The call tree should have the same structure as the top-down design!

Tree diagram for sort

You have already seen examples of function calls such as sin(), abs(), mod(), etc. Consider the following statement:

y = x ** 2 + sin(x) - 5.6
        

When this statement is executed, the program performs the following steps:

  1. Compute x ** 2
  2. Call the sin() function
    1. Send the argument x to the sin() function
    2. Execute the sin() function
    3. Return from the sin() function and return the sine of x to the statement containing the call to sin().
  3. Add the result of x ** 2 and the return value from sin(x)
  4. Subtract 5.6 from the result of x ** 2 + sin(x)
  5. Store the result in memory address y.

A Fortran subroutine is a subprogram that does not return a value, and is not called as part of an expression. A Fortran subroutine call is a separate statement by itself. You have seen examples of subroutine calls with write, print, and read. Consider the following program segment:

print *, 'Enter the radius of the circle:'
read *, radius
print *, 'The area of the circle is', PI * radius * radius
        

The sequence of events is as follows:

  1. Call the print subroutine
    1. Send the argument 'Enter the radius of the circle:' to the print subroutine.
    2. Jump to the print subroutine, which prints the string.
    3. Return from the print subroutine and continue with the next statement after the print.
  2. Call the read subroutine
    1. Pass the argument variable radius.
    2. Jump to the read subroutine, which reads input from the keyboard, converts it to the binary format appropriate for the variable radius, and stores the value in the memory location that radius represents.
    3. Return from the read subroutine.
  3. Compute PI * radius * radius
  4. Call print
    1. Pass arguments 'The area of the circle is' and the value of the expression PI * radius * radius to the print subroutine.
    2. Jump to the print subroutine, which prints the arguments.
    3. Return from print subroutine.