PROGRAM ARRAY3AS c c This program illustrates use of allocatable arrays accross c subprograms c c John Mahaffy 2/3/95 c IMPLICIT NONE INTEGER I,J,IERR,N,NDAT c c Declare A, B, and C to be arrays to be ALLOCATABLE c REAL, ALLOCATABLE :: A(:),B(:),C(:) REAL CSUM,CMAX,CMIN,AVERAGE,RAVERAGE c call size (NDAT) c c ALLOCATE must take place at the highest level the arrays are used. c I can't allocate the space in subroutines size or input. c c ALLOCATE (A(1:NDAT),B(NDAT),C(NDAT)) c call input(A,B,NDAT) if (NDAT.eq.0) then print *, 'No Lines in the Data File' stop endif call cprop(A,B,C,NDAT,AVERAGE,RAVERAGE,CMAX,CMIN) call writec(C,NDAT,AVERAGE,RAVERAGE,CMAX,CMIN) stop end SUBROUTINE SIZE (N) c c Read input file to determine data needs c REAL DUMMY INTEGER N OPEN(11,FILE='array3a.in',ERR=400) NDAT=0 10 READ(11,*,END=20) DUMMY N=N+1 GO TO 10 20 CONTINUE c c Having gone through Unit 11, I need to reposition it at the beginning c REWIND(11) return 400 print *, 'Can not open array3a.in' stop end c SUBROUTINE INPUT (A,B,N) c c Read A and B arrays c REAL DUMMY,A(N),B(N) INTEGER N c DO 30 I=1,N READ(11,*) A(I), B(I) 30 CONTINUE RETURN END SUBROUTINE CPROP(A,B,C,NDAT,AVERAGE,RAVERAGE,CMAX,CMIN) c c This subroutine doesn't care whether A, B, or C are allocatable. c but I will allocate RA for internal use. c REAL A(NDAT),B(NDAT),C(NDAT) REAL, ALLOCATABLE::RA(:) c c The next line does a default allocate, because "RB" is not in the c argument list, but NDAT is. RB is called an "automatic" array. c REAL RB(NDAT) REAL AVERAGE,RAVERAGE,CMAX,CMIN INTEGER NDAT,ISTAT LOGICAL lalloc c c Process as before c ALLOCATE (RA(1:NDAT)) RA(1:NDAT)=1./A(1:NDAT) RB(1:NDAT)=1./B(1:NDAT) C(1:NDAT)=A(1:NDAT)+B(1:NDAT) CSUM=SUM(C(1:NDAT)) CMIN=MINVAL(C(1:NDAT)) CMAX=MAXVAL(C(1:NDAT)) C AVERAGE=CSUM/NDAT RAVERAGE=SUM(RA(1:NDAT)+RB(1:NDAT))/(2*NDAT) c c In a Program with a lot of branching, c lalloc=allocated(RA) print *, 'Allocation status of RA is ', lalloc c c If you allocate an Array in a subroutine or function you should c deallocate it before returning. Otherwise the array enters an c undefined state, and Fortran 90 makes no guarantees about whether c you can reuse contents. The memory used is wasted (can't be reused by c another allocation, but is still credited to the total size of your c executing program. Also remember that the process of ALLOCATE and c DEALLOCATE in a subroutine or function that is used many times will c consume an excessive amount of computer time. c if (lalloc) then DEALLOCATE(RA,STAT=ISTAT) if (ISTAT.NE.0) then print *, 'Trouble deallocating RA in CPROP' endif lalloc=allocated(RA) print *, 'Allocation status of RA is ', lalloc endif c c RB is automatically deallocated at the RETURN, but the above c warning for excessive computer time associated with the ALLOCATE c and DEALLOCATE cycle, applies to this array too. In reality the c computer treats it no differently than I have RA c RETURN END SUBROUTINE WRITEC (C,NDAT,AVERAGE,RAVERAGE,CMAX,CMIN) REAL AVERAGE,RAVERAGE,SUM,CMAX,CMIN,C(1:NDAT) INTEGER NDAT,ISTAT WRITE(*,'(//,'' RESULTS FOR ELEMENTS 1 THROUGH '',I3,'' OF C'')') & NDAT WRITE(6,2002)AVERAGE,CMIN,CMAX 2002 FORMAT(' AVERAGE OF SELECTED ELEMENTS IN C = ', F8.3,/, & ' MINIMUM OF SELECTED ELEMENTS IN C = ', F8.3,/, & ' MAXIMUM OF SELECTED ELEMENTS IN C = ', F8.3) WRITE(6,*) 'Average of all reciprocals is: ',RAVERAGE WRITE(6,2003) C(1:NDAT) 2003 FORMAT(' C = ',/,(1P,8E10.2)) c RETURN 400 PRINT *,' Empty or missing input file: array3a.in' RETURN END