Professor Diomar Cesar Lobao

Universidade Federal Fluminense-Volta Redonda, RJ, Brasil

Diomar Cesar


Dept. Ciências Exatas - Exact Science Dept.

Search

array3as.f

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
Skip to content