|
|
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.