In either form the last statement of the program unit must be an END statement. Any other statements (except PROGRAM or BLOCK DATA statements) may be used within the program unit.
There are two statements provided especially for use in external procedures. The SAVE statement ensures that the values of local variables and arrays are preserved after the procedure returns control to the calling unit: these values will then be available if the procedure is executed subsequently. The RETURN statement may be used to terminate the execution of the procedure and cause an immediate return to the control of the calling unit. Execution of the END statement at the end of the procedure has exactly the same effect. Both of these are described in full later in the section.
Most Fortran systems also allow external procedures to be specified in languages other than Fortran: they can be called in the same way as Fortran procedures but their internal operations are, of course, beyond the scope of this book.
It is best to think of the subroutine as the more general form of procedure; the external function should be regarded as a special case for use when you only need to return a single value to the calling unit.
Here is a simple example of a procedure which converts a time of day in hours, minutes, and seconds into a count of seconds since midnight. Since only one value needs to be returned, the procedure can have the form of an external function. (In fact this is such a simple example that it would have been possible to define it as a statement function.)
*TSECS converts hours, minutes, seconds to total seconds. REAL FUNCTION TSECS(NHOURS, MINS, SECS) INTEGER NHOURS, MINS REAL SECS TIME = ((NHOURS * 60) + MINS) * 60 + SECS ENDThus if we use a function reference like TSECS(12,30,0.0) in an expression elsewhere in the program it will convert the time to seconds since midnight (about 45000.0 seconds in this case). The items in parentheses after the function name :
(12,30,0.0)
(NHOURS, MINS, SECS)
The next example performs the inverse conversion to the TSECS function. Since it has to return three values to the calling program unit the functional form is no longer appropriate, and a subroutine will be used instead.
*Subroutine HMS converts TIME in seconds into hours, mins,secs. SUBROUTINE HMS(TIME, NHOURS, MINS, SECS) REAL TIME, SECS INTEGER NHOURS, MINS NHOURS = INT(TIME / 3600.0) SECS = TIME - 3600.0 * NHOURS MINS = INT(SECS / 60.0) SECS = TIME - 60.0 * MINS ENDIn this case the subroutine could be executed by using a statement such as:
CALL HMS(45000.0, NHRS, MINS, SECS) WRITE(UNIT=*, FMT=*) NHRS, MINS, SECSHere the first argument transfers information into the subroutine, the other three are used to return the values which it calculates. You do not have to specify whether a particular argument is to transfer information in or out (or in both directions), but there are rules about the form of actual argument that you can use in each case. These are explained in full below.