Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://crydee.sai.msu.ru/f90/a10.html
Дата изменения: Sat Feb 17 17:37:02 1996 Дата индексирования: Mon Oct 1 19:43:59 2012 Кодировка: |
In Pascal the assignment of a new value to a variable not specified var is completely legal, but the new value is not returned to the calling program.
When an argument is specied as var then both the dummy and actual arguments will refer to the same storage area. This means that, if the quantity is changed within the procedure, the new value will be returned to the calling procedure. Such an argument is said to be a variable parameter. With the terminology of Fortran 90 it should have the attribute INTENT(INOUT).
In the following very small program the procedure sub has x and y as value parameters, and z as a variable parameter. Here the dummy arguments are x, y and z, while the actual arguments are a, b and c.
program example; var a, b, c : real; procedure sub(x, y : real; var z : real); begin y := y*y; z := x + y; end; begin a := 1; b := 10; sub(a, b, c); writeln(' a = ', a); (* Becomes 1 *) writeln(' b = ', b); (* Becomes 10 *) writeln(' c = ', c); (* Becomes 101 *) end.
In the following small Fortran program the subroutine SUB has X as an input variable, Y as an input and output variable, and Z as an output variable. The intent specification should therefore be as below. Please note that use of INTENT is optional but highly recommended. All compilers do not yet support it fully (all possible checks are not performed. Note that we have chosen different names for the actual arguments and for the formal arguments in the INTERFACE and in the SUBROUTINE. Usually the same name is chosen for all three cases.
Here the dummy arguments are X, Y and Z, the actual arguments are A, B and C, and the dummy arguments in the INTERFACE are S, T and U.
PROGRAM EXAMPLE IMPLICIT NONE INTERFACE SUBROUTINE SUB(S, T, U) REAL, INTENT(IN) :: S REAL, INTENT(INOUT) :: T REAL, INTENT(OUT) :: U END SUBROUTINE SUB END INTERFACE REAL :: A, B, C A = 1 B = 10 CALL SUB(A, B, C) WRITE(*,*) ' A = ', A ! Becomes 1 WRITE(*,*) ' B = ', B ! Becomes 100 WRITE(*,*) ' C = ', C ! Becomes 101 END PROGRAM EXAMPLE SUBROUTINE SUB(X, Y, Z) IMPLICIT NONE REAL, INTENT(IN) :: X REAL, INTENT(INOUT) :: Y REAL, INTENT(OUT) :: Z Y = Y**2 Z = X + Y END SUBROUTINE SUBIn Fortran there is really only one kind of argument usage, called argument association. There may still however be two cases two consider. If the argument is a scalar then the value of the actual argument may be copied to a memory location for the dummy argument, and on return (provided the value has been changed) the copy process will be repeated in the opposite direction, from the called program unit to the to the calling program unit or the main program. Please note that the first copy might be done to a register and not necessarily to the main RAM memory. The copy process back to the calling program unit naturally fails if the actual argument is a constant or an expression , for example 249 or SIN(X) or X+2, instead of a variable name. Normally no error message is obtained. The intent of the INTENT attribute is to give the compiler greater possibilities to check against similar inconsistencies.
Also note that if F(X) is a function which is called, then A in F(A) is a variable name, but (A) in F((A)) is a more general expression. This possibility to introduce an extra set of parenthesis in order to move from a variable to an expression works sometimes, but is very implementation dependent, and therefore strongly discouraged.
If the formal argument is an array then the mentioned copy process could mean a very large memory requirement, because the arrays would be stored twice, both in the calling and the called program unit. This is solved in such a way that the actual argument is used directly in the called subprogram. The actual array argument must have the same data type, kind and shape as the dummy argument, but there are a few exceptions from this general rule. Fortran assumes that the actual array has all the properties that were specified for the dummy array argument. The position for each array element is therefore calculated from this assumption. If the actual array is too different from the dummy array the wrong element can be referenced, with even fatal consequences. Usually this rule can be utilized in a satisfactory manner.
If the arguments are pointers or names of functions or subroutines the discussion above is not completely valid.
In the good old days IBM referred to that a variable was received by value regarding what was discussed above for scalars, and received by location regarding arrays (1977 about FORTRAN IV for IBM 360, an extension of Fortran 66). There even was a method to force received by location. The difference was rather important, but that is not the case any more. We used to have some problems with synchronization between index variables and variables in COMMON.
Fortran has storage association and sequence association. The Fortran 90 standard states in (14.6.3) that storage association is the association of two or more data objects that occurs when two or more storage sequences share or are aligned with one or more storage units, and in (12.4.1.4) that sequence association is the order that Fortran requires when an array is associated a formal argument. The rank and shape of the actual argument need not agree with the rank and shape of the dummy argument.