Subroutines are similar to functions, yet differ from them in several ways. The most important one
is that there is no value associated with the name of the subroutine or, in other words, subroutine
has no return statement. Subroutine is invoked using a call
statement from anywhere else in
your F77 code. Keywords subroutine
and end
are used to define the beginning and end of
a subroutine. Compared to functions which usually have at least one argument, subroutines are often
used without any arguments.
The best way to contrast the difference between a function and a subroutine is to rewrite the function for the calculation of the average of three numbers as a subroutine. This might look as follows:
subroutine AVERAGE(a,b,c,avg) implicit none real a, b, c, avg avg = (a+b+c)/3.0 endThe difference between this expression and the function in the previous section is that the subroutine contains one more parameter,
avg
. This serves as a variable in which the
subroutine returns the computed average of the three numbers a
, b
and c
. To
call this subroutine, you do not have to declare the type of AVERAGE
, as it was needed if it
were a function. Simply write:
: CALL average(num1,num2,num3,navg) :The calculated average of the three numbers
num1
, num2
, num3
is then returned
in the variable navg
.
The most striking difference between functions and subroutines becomes obvious once you have to
write a subprogram that returns more than one value. If you still doubt that you will ever need
subroutines, check with the following example.
Problem: An interaction between two atoms can be described using the Lennard-Jones potential
Solution:
program CALCMINE implicit none real sigma, eps, r0, Phi0 parameter( sigma=3.405, eps=0.010323 ) call LJ_MIN_E(sigma,eps,r0,Phi0) write(*,'("Equilibrium separation = ",F5.3," A")') r0 write(*,'("Energy at equilibrium = ",F8.6," eV")') Phi0 end !------------------------------------------------------------------ subroutine LJ_MIN_E(sigma,eps,r0,Phi0) implicit none real sigma, eps, r0, Phi0 r0 = sigma*2**(1.0/6.0) Phi0 = 4*eps*((sigma/r0)**12-(sigma/r0)**6) end
The equilibrium separation corresponds to an extremum of the L-J potential, . This gives . The corresponding energy is then obtained by substituting in the expression for . The output should look as follows:
Equilibrium separation = 3.822 A Energy at equilibrium = -.010323 eV
Last command which is worth mentioning here is return
that causes an immediate end of a
running subroutine and return to the program which originally called it. This is very convenient
once you want to leave a subroutine in the middle and forget the remaining commands. Without using
return
, you would need to use the goto
command for an unconditional jump to the
end
identifier of your subroutine.
Roman Gröger (2015-09-23)