next up previous

Modules



Nelle applicazioni di programmazione ingegneristiche ,si incontra spesso il caso di parametri, variabili e subprograms 
che devono essere ripartiti in parecchie unità di programma. Il fortran 90 fornisce un'unità speciale di programma 
conosciuta come  MODULE che impacca convenientemente le collezioni di dichiarazioni e di subprograms in modo da poterle
importare in altre unità di programma.La funzionalità dell'unità del modulo è simile a quella dell'archivio di 
intestazione di C.

  1)Moduli semplici

Una forma d'un modulo è come segue:


   MODULE name
      specifications
   END MODULE name


Si noti che questa è la forma più semplice dell'unità del modulo.Esistono forme più generali che permettono l'inclusione dei 
subprograms e delle procedure. Richiameremo soltanto la forma più semplice dell'unità del modulo . Un modulo di programma 
è reso accessibile alle varie unità di programma attraverso l'istruzione USE.

Considerare il seguente programma che usa un modulo nel calcolo dell'area d'un cerchio:


MODULE Circle
!---------------------------------------------------------------------
!
!  Modulo che contiene le definizioni delle variabili necessarie per
!  il calcolo dell'area di un cerchio noto il raggio
!
!---------------------------------------------------------------------
   REAL, PARAMETER :: Pi = 3.1415927
   REAL :: radius
END MODULE Circle

PROGRAM Area
!---------------------------------------------------------------------
!
!  Questo programma calcola l'area di un cerchio noto che sia il raggio
!
!  Uses:  MODULE Circle
!         FUNCTION Area_Circle (r)
!
!---------------------------------------------------------------------
USE Circle, ONLY : radius
IMPLICIT NONE

INTERFACE 
   FUNCTION Area_Circle (r)
     REAL, INTENT(IN) :: r
   END FUNCTION Area_Circle
END INTERFACE


!  Prompt user per il valore del raggio
write(*, '(A)', ADVANCE = "NO") "Digita il valore del raggio:  "
read(*,*) radius

! Scrive l'area utilizzando la function call
write(*,100) "Area del cerchio di raggio", radius, " è", &
            Area_Circle(radius)
100 format (A, 2x, F6.2, A, 2x, F11.2)

END PROGRAM Area

!-----Area_Circle----------------------------------------------------
!
!  Funzione per il calcolo dell'area del cerchio
!
!---------------------------------------------------------------------
FUNCTION Area_Circle(r)
USE Circle, ONLY : Pi

IMPLICIT NONE
REAL :: Area_Circle
REAL, INTENT(IN) :: r

Area_Circle = Pi * r * r

END FUNCTION Area_Circle


In questo esempio, definiamo un modulo che dichiara il tipo delle due variabili reali pi e raggio. In più, in questo
modulo,dichiariamo il valore del parametro pi. Per usare il modulo nel programma principale, impieghiamo l'istruzione
USE. Usiamo una forma speciale dell' istruzione USE che specifica  che siamo SOLTANTO interessati al valore del raggio
nel programma principale,cioè nel programma del modulo viene utilizzato un solo componente. Similmente, usiamo soltanto
il parametro pi nel subprogram Area_Circle attraverso l'istruzione USE che compare in quella procedura.

L'istruzione USE DEVE  comparire all'inizio della parte di dichiarazione dell'unità di programma che usa il modulo!!
Deve comparire ANCHE PRIMA dell'istruzione IMPLICIT NONE!


   2)Moduli per l'allocazione dinamica di array 

Ci sono periodi in cui potete desiderare di dichiarare un array come allocatable. Tuttavia, potete desiderare assegnare 
la relativa memoria in un subprogram piuttosto che nel programma principale. Purtroppo, gli array allocatable non 
possono essere passati come argomenti convenzionali ai subprograms. La costruzione del modulo fornisce un modo per 
passare gli array come dinamicamente allocatable a parecchie unità di programma.
Considerare il seguente esempio:


MODULE Dyn_Array
!---------------------------------------------------------------------
!
!  Modulo che contiene definizioni necessarie per allocare dinamicamente
!  i valori di un array
!
!---------------------------------------------------------------------
   INTEGER :: n
   REAL, DIMENSION(:), ALLOCATABLE :: A
END MODULE Dyn_Array

PROGRAM Play_with_Array
!---------------------------------------------------------------------
!
!  This program calls a subroutine to read in the values of
!  a dynamically allocated array A and calls several 1D intrinsic
!  array functions
!
!  Uses:  MODULE Dyn_Array
!         SUBROUTINE Get_Data
!         SUBROUTINE Dealloc_Array
!
!---------------------------------------------------------------------
USE Dyn_Array
IMPLICIT NONE

INTERFACE 
   SUBROUTINE Get_Data
   END SUBROUTINE Get_Data
END INTERFACE

INTERFACE 
   SUBROUTINE Dealloc_Array
   END SUBROUTINE Dealloc_Array
END INTERFACE

! Declare local variables
REAL :: Prod_A, Sum_A

! Call subroutine to read in data for array A
CALL Get_Data

! Use intrinsic functions to generate data
Prod_A = PRODUCT(A)

! Write out product of elements of array A
write(*,100) "The product of the elements of array A area", &
              Prod_A

! Use intrinsic function to generate more data
Sum_A = SUM(A)

! Write out sum of elements of array A
write(*,100) "The sum of the elements of array A are", &
             Sum_A 

! Now, deallocate memory containing array A
CALL Dealloc_Array

! Place for format statement to live
100 format (A, 2x, F11.2)

END PROGRAM Play_with_Array

!-----Get_Data--------------------------------------------------------
!
!  Subroutine to read in the number of values to fill A array,
!  allocate space, and to assign the values to A
!
!  Uses:  MODULE Dyn_Array
!
!---------------------------------------------------------------------
SUBROUTINE Get_Data
USE Dyn_Array

IMPLICIT NONE

! Declare local variables
INTEGER :: AllocateStatus

! Read in number of array elements from user
write(*,'(A)', ADVANCE = "NO") "Input the number of elements desired:  "
read(*,*) n

! Allocate storage for array A accordingly
ALLOCATE( A(n), STAT = AllocateStatus)
IF (AllocateStatus /= 0) STOP "*** Not enough memory ***"

! Read in values for A
write(*, '(A)', ADVANCE = "NO") "Input array values:  "
read(*,*) A

END SUBROUTINE Get_Data

!-----Dealloc_Array---------------------------------------------------
!
!  Subroutine to deallocate array space
!
!  Uses:  MODULE Dyn_Array
!
!---------------------------------------------------------------------
SUBROUTINE Dealloc_Array
USE Dyn_Array

IMPLICIT NONE

! Declare local variables
INTEGER :: DeAllocateStatus

! Deallocate storage for array A 
DEALLOCATE( A, STAT = DeAllocateStatus)
IF (DeAllocateStatus /= 0) STOP "*** Trouble deallocating ***"

END SUBROUTINE Dealloc_Array


Qui usiamo il modulo Dyn_Array per dichiarare l' array A come reale allocatable. Il numero intero n sarà il
formato dell' array quando il relativo valore è immesso dall'utente nel sottoprogramma Get_Data.