|
|
FUNCTION pythagoras(a, b) ! The enclosing function IMPLICIT NONE REAL :: pythagoras, a, b REAL :: s s = square(a) + square(b) pythagoras = sqrt(s) RETURN CONTAINS ! internal functions follow... REAL FUNCTION square(x) REAL :: x print *, "a = ", a, ", b = ", b !! You can access outer variables square = x*x return END FUNCTION square END FUNCTION pythagoras |
Example:
INTEGER FUNCTION myFunction1() IMPLICIT NONE INTEGER :: i ! Local variable myFunction1 = i i = i + 1 RETURN END FUNCTION |
I.e., "local" variables are accessible only inside that function and its internal functions
INTEGER FUNCTION myFunction1() IMPLICIT NONE INTEGER :: i !! Different variables myFunction1 = i i = i + 1 RETURN END FUNCTION ! ============================================ INTEGER FUNCTION myFunction2() IMPLICIT NONE INTEGER :: i !! Different variables myFunction2 = i i = i + 1 RETURN END FUNCTION |
I.e., local variables in Fortran are not created when the program enters its scope (as in C++....
Local variables in Fortran functions are created when the program begins execution.
INTEGER FUNCTION myFunction1() IMPLICIT NONE INTEGER :: i myFunction1 = i i = i + 1 RETURN END FUNCTION ! ============================================ INTEGER FUNCTION myFunction2() IMPLICIT NONE INTEGER :: i myFunction2 = i i = i + 1 RETURN END FUNCTION ! ============================================ PROGRAM internal PRINT *, myFunction1() PRINT *, myFunction1() ... PRINT *, myFunction2() PRINT *, myFunction2() ... END |
Because the local variables i are created at the start of the program, they will retain the value between function invocations
As a result, you will see the output:
0 (i in myFunction1() 1 ... 0 (i in myFunction2() 1 ... |
int myFunction1() { int i, r; r = i; i = i + 1; return(r); } int myFunction2() { int i, r; r = i; i = i + 1; return(r); } int main(int argc, char *argv[]) { cout << myFunction1() << endl; cout << myFunction1() << endl; ... cout << myFunction2() << endl; cout << myFunction2() << endl; ... } |
Because the local variables i are created each time the function runs, they will NOT retain the value between function invocations
As a result, you will see the output:
??? <------- First time there is "garbage" on the stack... x x <------- Same value each time..... x ... x x x ... |
This will result in that behavior of C++:
|
SAVE variable |
statement that save the value of a local variable between invocations
SUBROUTINE mySubr(X, Y, Z) IMPLICIT NONE REAL :: X, Y, Z REAL :: A, B, C !! Local variables !! (may lose their value between !! invocation in the future)... SAVE A !! A will retain the value between invocation ... END |
(Because in Fortran 77, local (and parameter) variables are NOT created when execution enters the recusive function )
However, Fortran 90 does.
Example:
RECURSIVE FUNCTION fac(N) RESULT(facResult) IMPLICIT NONE INTEGER :: facResult !! Return type INTEGER, INTENT(IN) :: N if ( N == 1 ) then facResult = 1 else facResult = N * fac(N-1) end if END FUNCTION |
The RECURSIVE keyword make the Fortran 90 compiler to use a completely different compilation technique for a function.
|
Shared variables can be accessed from within any program or subprogram
Shared variables are effectively "global" variables .
COMMON [/BlockName/] var1, var2, .... |
PROGRAM myProg INTEGER i1, i2 REAL f1, f2 COMMON /John/ i1, f1 ! Must be in same order !!! i1 = 1111 f1 = 2222 i2 = 3333 f2 = 24444 CALL mySubr print *, i1, f1, i2, f2 END |
The subroutine is able to access the shared variables i1 and f1
|
module ModuleName .. .. content of module (discussed later) end module |
In the module, you can specify zero or more definitions for:
|
MODULE ModuleName [PRIVATE|PUBLIC] !! Default is PUBLIC [PRIVATE::|PUBLIC::] variable definitions... END MODULE [ModuleName] |
Meaning:
|
MODULE myModule INTEGER i1 REAL f1 END MODULE |
f90 -c ModuleFileName.f90 |
USE ModuleName |
|
MODULE myModule INTEGER i1 REAL f1 END MODULE PROGRAM myProg USE myModule IMPLICIT NONE i1 = 1111 f1 = 2222 CALL mySubr --------------------------------+ | print *, i1, f1 | END | | SUBROUTINE mySubr <----------------------------+ USE myModule IMPLICIT NONE i1 = 3333 f1 = 4444 END |
The subroutine mySubr will be able to modify the global variables
Have not look into that yet.... I plan to when the Fortran 2003 compiler is available.