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
|