SUBROUTINE MySubrName(Param1, Param2, ...) IMPLICIT NONE ! Recommended Type [, INTENTION] Param1 ! Parameter declaration Type [, INTENTION] Param2 ! (looks strange being inside the function) .... *** Variable definitions *** Subroutine Body (statments) RETURN ! Multiple RETURN allowed END ! Ends subroutine definition |
|
CALL SubroutineName(param1, param2, ...) |
! =================================================== ! Subroutinbe returns a + (a+1) + ... + b ! =================================================== SUBROUTINE SerieSum(a, b, sum) IMPLICIT NONE ! Recommended INTEGER, INTENT(IN) :: a INTEGER, INTENT(IN) :: b INTEGER, INTENT(OUT) :: sum INTEGER :: i sum = 0 DO i = a, b sum = sum + i END DO RETURN END |
FUNCTION MyFuncName(Param1, Param2, ...) [result( resultName )] IMPLICIT NONE ! Recommended Type [, Intention] :: Param1 Type [, Intention] :: Param2 .... [Type :: MyFuncName | Type :: resultName ] *** Variable definitions *** Subroutine Body (statments) Returning value with: MyFuncName = Value ! Assign return value or: resultName = Value ! Assign return value RETURN ! Multiple RETURN allowed END ! Ends subroutine definition |
Variable = FunctionName(param1, param2, ...) |
! =================================================== ! Function returns a + (a+1) + ... + b ! =================================================== FUNCTION SerieSum(a, b) IMPLICIT NONE ! Recommended INTEGER, INTENT(IN) :: a INTEGER, INTENT(IN) :: b INTEGER SerieSum !! Return type INTEGER :: i SerieSum = 0 DO i = a, b SerieSum = SerieSum + i END DO RETURN END ! Ends subroutine definition |
NOTE:
|
When the function returns , the value in the RESULT variable is returned to the caller
! =================================================== ! Function with a RESULT variable ! =================================================== FUNCTION SerieSum(a, b) RESULT(x) IMPLICIT NONE ! Recommended INTEGER, INTENT(IN) :: a INTEGER, INTENT(IN) :: b INTEGER x !! Return type of return variable INTEGER :: i x = 0 DO i = a, b x = x + i END DO RETURN END ! Ends subroutine definition |
When a function returns a built-in type , you can use:
|
to return the function value
We will see example of these later in click here
PROGRAM Demo IMPLICIT NONE REAL x, y <--- Real INTEGER sum INTEGER, EXTERNAL :: SerieSum !! No information on input parameters read*, x read*, y sum = SerieSum(x,y) <------- Trouble !!!! print*, "Serie sum = ", sum print* STOP END |
So when the compiler translates the main program , the function definition has not been processed yet.
The compiler will detect the error if the function definition preceeds the main program) |
Start number a = 1 End number b = 2 Serie sum = 1069547520 |
Difference in variable types caused this error...
Interfaces provide knowledge to the compiler about a subroutine/function during compilation.
INTERFACE One or more Subroutine/Function description END INTERFACE |
PROGRAM Demo IMPLICIT NONE REAL x, y <--- Real INTEGER sum INTERFACE FUNCTION SerieSum(a,b) INTEGER SerieSum INTEGER, INTENT(IN) :: a !! <<--- Integer INTEGER, INTENT(IN) :: b !! <<--- Integer END FUNCTION END INTERFACE read*, x read*, y sum = SerieSum(x,y) <==== Parameter type error detected !!! print*, "Serie sum = ", sum print* STOP END |
You will get compile errors:
ERROR: The type of the actual argument, "REAL", does not match "INTEGER", the type of the dummy argument. |
Try changing the variables to the matching type...
! =================================================== ! Function returns f(a) + f(a+1) + ... + f(b) ! =================================================== FUNCTION SerieSum(f, a, b) ... END |
If f(x) = x2 then the function SerieSum() will compute:
a2 + (a+1)2 + (a+2)2 + ... + b2 |
If f(x) = x3 then the function SerieSum() will compute:
a3 + (a+1)3 + (a+2)3 + ... + b3 |
And so on
|
Example:
! =================================================== ! Function returns f(a) + f(a+1) + ... + f(b) ! ! f is a "function parameter" ! =================================================== FUNCTION SerieSum(f, a, b) IMPLICIT NONE INTEGER SerieSum !! Function return value INTEGER, INTENT(IN) :: a INTEGER, INTENT(IN) :: b interface !! Declare a function parameter function f(x) integer f; integer, intent(in) :: x; end function f end interface INTEGER :: i SerieSum = 0 DO i = a, b SerieSum = SerieSum + f(i) END DO RETURN END |
Example:
PROGRAM Test *** declare SerieSum *** x = SerieSum(f, a, b) END |
Example:
PROGRAM Demo IMPLICIT NONE interface function SerieSum(f,x,y) integer SerieSum !! Return value of SerieSum interface function f(z) integer f; integer, intent(in) :: z; end function f end interface integer, intent(in) :: x; integer, intent(in) :: y; end function end interface .... END |
The header file for function f(x)
func.h |
---|
interface function f(x) integer f; integer, intent(in) :: x; end function end interface |
The implementation file for function f(x)
func.f90 |
---|
! =================================================== ! Function f(x) returns x*x ! =================================================== INTEGER FUNCTION f(x) IMPLICIT NONE INTEGER, INTENT(IN) :: x f = x*x RETURN END |
The header file for function SerieSum(f,x,y)
SerieSum.h |
---|
interface function SerieSum(f,x,y) integer SerieSum interface function f(z) integer f; integer, intent(in) :: z; end function f end interface integer, intent(in) :: x; integer, intent(in) :: y; end function end interface |
The implementation file for function SerieSum(f,x,y)
func.f90 |
---|
! =================================================== ! Function returns f(a) + f(a+1) + ... + f(b) ! =================================================== FUNCTION SerieSum(f, a, b) IMPLICIT NONE INTEGER SerieSum INTEGER, INTENT(IN) :: a INTEGER, INTENT(IN) :: b include "func.h" INTEGER :: i SerieSum = 0 DO i = a, b SerieSum = SerieSum + f(i) END DO RETURN END |
The main program file that uses functions SerieSum(f,x,y) and f(x)
main.f90 |
---|
PROGRAM Demo IMPLICIT NONE include "func.h" include "SerieSum.h" INTEGER :: x, y, sum print*, "Start number a = " read*, x print*, "End number b = " read*, y sum = SerieSum(f, x, y) ! *** Pass f to SerieSum print*, "Serie sum = ", sum print* STOP END |
Compile separately with:
f90 -c func.90 f90 -c SerieSum.90 f90 -c main.90 Link: f90 main.o SerieSum.o func.o |
FUNCTION pythagoras(a, b) ! The enclosing function IMPLICIT NONE REAL pythagoras REAL a, b REAL s s = square(a) + square(b) pythagoras = sqrt(s) RETURN CONTAINS ! internal functions follow... FUNCTION square(a) REAL square REAL a square = a*a return END FUNCTION ! "FUNCTION" is required END FUNCTION pythagoras |