| Документ взят из кэша поисковой машины. Адрес
оригинального документа
: http://star.arm.ac.uk/f77to90/c12.html Дата изменения: Sat Feb 17 19:16:24 1996 Дата индексирования: Mon Oct 1 21:25:07 2012 Кодировка: Поисковые слова: rainbow | 
The increased security is obtained not only through that each variable, which shall be used as a pointer, must be given an attribute POINTER, but also that all variables, that will be pointed to, must be given an attribute TARGET. An example explaining how to do this follows.
       REAL, TARGET          :: B(10,10)
       REAL, POINTER         :: A(:,:)
       A => B
   The matrix B has been specified completely, i.e.  with the
dimensions given explicitly. In addition, it has been stated that it
can be the target of a pointer. The matrix A, which can be used as a
pointer, has to be declared as a matrix, i.e. to be given a correct
number of dimensions, a correct rank, but the extent for this is
decided later, at the assignment (and in reality the assignment is a
pointer-association) which is done with the symbols =>. Please note
that the pointer assignment does not mean that the data in the matrix
B  is copied over to the matrix A  (which would have taken 
relatively
large resources), but it is merely a new address that is generated. To
"move" data with the pointer concept will therefore be very efficient.
As an alternative the pointer can become associated with the statement
ALLOCATE, and be disassociated with DEALLOCATE, as in the following
example.
       ALLOCATE (A(5,5))
       DEALLOCATE (A)
   There is also an internal function ASSOCIATED  in order to
investigate if a pointer is associated (and if it is associated with a
certain target) and a statement NULLIFY  in order to terminate the
association.
IF ( ASSOCIATED (A) ) WRITE(*,*) ' A is associated ' IF ( ASSOCIATED (A, B) ) WRITE(*,*) ' A is associated with B' NULLIFY (A)Please remember that a pointer in Fortran 90 has both type and rank, and that these must agree with the corresponding target. This increases the security at the use of pointers, it is therefore not possible by mistake to let a pointer change values of variables of other (different) data types. The fact that you have to specify that a variable can be a target also increases both security and efficiency of the compilation.
Important application of pointers are lists and trees, and especially dynamic arrays.
       REAL, TARGET   :: A
       REAL, POINTER  :: P, Q
       A = 3.1416
       P => A
       Q => P
       A = 2.718
       WRITE(*,*) Q
   Here the value of Q  equals 2.718 since both P  
and Q  point towards
the same variable A  and that one has just changed its value from
3.1416 to 2.718.  We now make a simple variation.
       REAL, TARGET  :: A, B
       REAL, POINTER :: P, Q
       A = 3.1416     
       B = 2.718
       P => A  
       Q => B
   Now both the values of A  and P  are equal to 3.1416 
and the values
of both B  and Q  are 2.718.  If we now give the 
statement 
Q = Pall four variables will get the value 3.1416, which means that an ordinary assignment of pointer variables has the same effect as the conventional assignment
B = AIf we instead give a pointer association
Q => Pthen the three variables A, P and Q all have the value 3.1416, while B contains the value 2.718. In the second case Q only points to the same variable as P while in the first case Q becomes the same as P, and the value addressed by Q becomes equal to the value addressed by P.
       REAL, TARGET   :: B(10,10)
       REAL, POINTER  :: A(:), C(:)
        A => B(4,:)   ! vector A becomes the fourth row
        C => B(:,4)   ! and vector C becomes the fourth
                      ! column of the matrix B
   It is not necessary to take the whole section, you can take only
a partial section.  In  the  following  example you can take a partial
matrix WINDOW  of a large matrix MATRIX.
       REAL, TARGET          :: MATRIX(100,100)
       REAL, POINTER         :: WINDOW(:,:)
       INTEGER               :: N1, N2, M1, M2
       WINDOW => MATRIX(N1:M1, N2:M2)
   If you later wish to change a dimension of the partial matrix
WINDOW  you only need to make a new pointer association. Please note
that the indices in WINDOW  are not from N1  to 
M1  and 
from N2  to
M2  but from 1  to  M1-N1+1  and from 
1 
 to M2-N2+1.
There does not exist arrays of pointers directly in Fortran 90, but you can construct such facilities by creating a new data type. An example is to store a lower (or left) triangular matrix with rows with varying length. First introduce a new data type ROW
       TYPE ROW
              REAL, POINTER   :: R(:)
       END TYPE
and then specify the two lower triangular matrices V  
and L  as vectors
of rows with varying length
       INTEGER                :: N
       TYPE(ROW)              :: V(N), L(N)
after which you can allocate the matrix V  as below (and in the
corresponding way you can allocate the matrix L)
       DO I = 1, N
              ALLOCATE (V(I)%R(1:I))    
              ! Various length of rows
       END DO
   The statement 
V = Lthen becomes equivalent with
V(I)%R => L(I)%Rfor all the components, i.e. all values of I. Please note that in this application there is no TARGET required.
An alternative method has however been suggested by Arie ten Cate, using a module with an ALLOCATEd and SAVEd array. An example is available.
We however use an INTERFACE with pointers in the main program and allocate, also using pointers, a vector in the subroutine. In this way we get a dynamically allocated vector.
      PROGRAM MAIN_PROGRAM
      INTERFACE
         SUBROUTINE SUB(B)
         REAL, DIMENSION (:), POINTER :: B
         END SUBROUTINE SUB
      END INTERFACE
      REAL, DIMENSION (:), POINTER :: A
      CALL SUB(A) 
!     Now we can use the vector A.
!     Its dimension was determined in the subroutine,
!     the number of elements is available as SIZE(A).
      END PROGRAM MAIN_PROGRAM
      SUBROUTINE SUB(B)
      REAL, DIMENSION (:), POINTER :: B
      INTEGER M
!     Now we can assign a value to M, for example
!     through an input statement.
!     When M has been assigned we can allocate B 
!     as a vector.
      ALLOCATE (B(M))
!     Now we can use the vector B.
      END SUBROUTINE SUB
       Note: The method above is even more useful for allocating
          matrices, see exercise 12.3.
   (12.2) Specify  two  pointers, and let one of them point to a whole
vector and the other one point to the  seventh  element  of  the  same
vector.
Solution.
(12.3)  Use pointers to specify a matrix in such a way, that it is
given its size (its extent) in a subroutine but can be used in the
main program. 
Solution.