Sei sulla pagina 1di 5

!Method for creating and allocating deferred-shape objects.

INTEGER, ALLOCATABLE :: matrix(:,:) REAL, ALLOCATABLE :: vector(:) CHARACTER, ALLOCATABLE :: c1, c2 (LEN=:), c3 (Len=:)(:) ... ALLOCATE(matrix(3,5),vector(-2:N+2)) ALLOCATE(c1, c2(Len=5), c3(LEN=3)(2:4) ... The following example shows a type declaration statement specifying the ALLOCATABLE attribute: REAL, ALLOCATABLE :: Z(:, :, :) The following is an example of the ALLOCATABLE statement: REAL A, B(:) ALLOCATABLE :: A(:,:), B Statement and Attribute: Specifies that an object or a procedure is a pointer (a dynamic variable). A pointer does not contain data, but points to a scalar or array variable where data is stored. A pointer has no initial storage set aside for it; memory storage is created for the pointer as a program runs. REAL, POINTER :: arrow (:) REAL, ALLOCATABLE, TARGET :: bullseye (:,:) ! The following statement associates the pointer with an unused ! block of memory. ALLOCATE (arrow (1:8), STAT = ierr) IF (ierr.eq.0) WRITE (*,'(/1x,a)') 'ARROW allocated' arrow = 5. WRITE (*,'(1x,8f8.0/)') arrow ALLOCATE (bullseye (1:8,3), STAT = ierr) IF (ierr.eq.0) WRITE (*,*) 'BULLSEYE allocated' bullseye = 1. bullseye (1:8:2,2) = 10. WRITE (*,'(1x,8f8.0)') bullseye ! The following association breaks the association with the first ! target, which being unnamed and unassociated with other pointers, ! becomes lost. ARROW acquires a new shape. arrow => bullseye (2:7,2) WRITE (*,'(/1x,a)') 'ARROW is repointed & resized, all the 5s are lost' WRITE (*,'(1x,8f8.0)') arrow NULLIFY (arrow) IF (.NOT.ASSOCIATED(arrow)) WRITE (*,'(/a/)') ' ARROW is not pointed' DEALLOCATE (bullseye, STAT = ierr) IF (ierr.eq.0) WRITE (*,*) 'Deallocation successful.' END INTEGER ERR INTEGER, ALLOCATABLE :: A(:), B(:) ... ALLOCATE(A(10:25), B(SIZE(A)), STAT=ERR) ! A is invalid as an argument ! to function SIZE

Example
!Method for creating and allocating deferred shape arrays.

INTEGER,ALLOCATABLE::matrix(:,:) REAL, ALLOCATABLE:: vector(:) . . . ALLOCATE (matrix(3,5),vector(-2:N+2)) . . . The following shows another example of the ALLOCATE statement: INTEGER J, N, ALLOC_ERR REAL, ALLOCATABLE :: A(:), B(:,:) ... ALLOCATE(A(0:80), B(-3:J+1, N), STAT = ALLOC_ERR) Consider the following: REAL(KIND=8) :: r(15, 25) REAL(KIND=8), ALLOCATABLE :: s(:,:), t(:,:) ... ALLOCATE(s,SOURCE=r) ALLOCATE(t,SOURCE=r) The following example shows a program that performs virtual memory allocation. This program uses Fortran standard-conforming statements instead of calling an operating system memory allocation routine. ! Program accepts an integer and displays square root values INTEGER(4) :: N READ (5,*) N ! Reads an integer value CALL MAT(N) END ! Subroutine MAT uses the typed integer value to display the square ! root values of numbers from 1 to N (the number read) SUBROUTINE MAT(N) REAL(4), ALLOCATABLE :: SQR(:) ! Declares SQR as a one-dimensional ! allocatable array ALLOCATE (SQR(N)) ! Allocates array SQR DO J=1,N SQR(J) = SQRT(FLOATJ(J)) ! FLOATJ converts integer to REAL ENDDO WRITE (6,*) SQR ! Displays calculated values DEALLOCATE (SQR) ! Deallocates array SQR REAL, POINTER :: A(:,:), B(:), C(:,:) INTEGER, ALLOCATABLE :: I(:) REAL, ALLOCATABLE, TARGET :: D(:, :), E(:) ... ALLOCATE (A(2, 3), I(5), D(SIZE(I), 12), E(98) ) C => D ! Pointer assignment statement B => E(25:56) ! Pointer assignment to a section

Pointers
An array can be declared as a pointer (just like allocatable). A pointer can be used in an allocate statement just as if it had been declared allocatable. Pointers seem to be needed in order to pass assumed shape arrays. For instance,let us allocate an array in the main program and pass it to a subroutine.

program pointer real*8, pointer

:: array(:,:)

interface subroutine sub(array) real*8, pointer :: array(:,:) end subroutine end interface allocate(array(4,4)) call sub(array) end end program subroutine sub(array) real*8, pointer :: array(:,:)

The interface block seems to be necessary to pass the array correctly


NAMELIST /NLIST/ A,B,C REAL A /1.5/ INTEGER B /2/ CHARACTER*5 C /'ABCDE'/ READ (5,NML=NLIST) WRITE (6,NML=NLIST) END

During execution, if a blank followed by ? is entered on a terminal device, the following values are displayed:
&NLIST A B C /

If a blank followed by =? is entered, the following values are displayed:


&NLIST A = 1.500000 B = 2, C = ABCDE ,

The following is an example of the ALLOCATE statement:


INTEGER J, N, ALLOC_ERR REAL, ALLOCATABLE :: A(:), B(:,:) ... ALLOCATE(A(0:80), B(-3:J+1, N), STAT = ALLOC_ERR)

For More Information:


REAL FUNCTION TANH(X) TSINH(Y) = EXP(Y) - EXP(-Y) TCOSH(Y) = EXP(Y) + EXP(-Y) TANH = TSINH(X)/TCOSH(X) RETURN ENTRY SINH(X) SINH = TSINH(X)/2.0

RETURN ENTRY COSH(X) COSH = TCOSH(X)/2.0 RETURN END FUNCTION ROOT(A) X = 1.0 DO EX = EXP(X) EMINX = 1./EX ROOT = X - ((EX+EMINX)*.5+COS(X)-A)/((EX-EMINX)*.5-SIN(X)) IF (ABS((X-ROOT)/ROOT) .LT. 1E-6) RETURN X = ROOT END DO END Alternatively, if the file names can not be generated according a rule, you may use some libraries which enable to get a list of files in a directory. One possibility could be my modFileSys library, where you could do it for arbitrary directory content the following way:

program test_ls use filesys_module type(dirdesc) :: dir character(:), allocatable :: path call opendir("./", dir) path = dir%next_filename() do while (len(path) > 0) write(*, "(A)") path path = dir%next_filename()
end do

end program test_ls This ! ! ! program prompts for the name of a data file. The INQUIRE statement then determines whether the file exists. If it does not, the program prompts for another file name. CHARACTER*12 fname LOGICAL exists ! Get the name of a file: 100 WRITE (*, '(1X, A\)') 'Enter the file name: ' READ (*, '(A)') fname ! INQUIRE about file's existence: INQUIRE (FILE = fname, EXIST = exists) IF (.NOT. exists) THEN WRITE (*,'(2A/)') ' >> Cannot find file ', fname GOTO 100 END IF END CHARACTER*64 filename WRITE (*, '(A\)') ' enter file to create: '

READ (*, '(A)') filename ! Open the file for formatted sequential access as unit 7. ! Note that the specified access need not have been specified, ! since it is the default (as is "formatted"). OPEN (7, FILE = filename, ACCESS = 'SEQUENTIAL', STATUS = 'NEW') The following example opens an existing file called DATA3.TXT: ! Open a file created by an editor, "DATA3.TXT", as unit 3: OPEN (3, FILE = 'DATA3.TXT')

Using Environment Variables


You can use shell commands to set the appropriate environment variable to a value that indicates a directory (if needed) and a file name to associate a unit with an external file.

Supplying a File Name in an OPEN Statement


The FILE specifier in an OPEN statement typically specifies only a file name (such as filnam) or contains both a directory and file name (such as /usr/proj/filnam). For example: OPEN (UNIT=7, FILE='FILNAM.DAT', STATUS='OLD') The DEFAULTFILE specifier in an OPEN statement typically specifies a pathname that contains only a directory (such as /usr/proj/) or both a directory and file name (such as /usr/proj/testdata).

Potrebbero piacerti anche