Unità di programma: Moduli

Più unità di programma (SUBROUTINE o FUNCTION) e dichiarazioni di variabili e costanti possono essere raggruppate in un MODULE per poter essere messe a disposizione di altre unità di programma. La parte iniziale del modulo contiene le dichiarazioni dei dati appartenenti al modulo stesso, mentre la parola chiave CONTAINS introduce le unità di sottoprogramma relative al modulo stesso. Altre unità di programma, compresi altri MODULE, possono accedere ai dati e ai sottoprogrammi di un modulo mediante l'istruzione USE <nome-modulo> posta all'inizio dell'unità di programma stessa. I dati dichiarati nel modulo sono globali, per cui tutte le unità che fanno USE di quel MODULE accedono alle stesse locazioni di memoria

Le unità di sottoprogramma dichiarate in un MODULE hanno un'INTERFACE definita implicitamente dal compilatore, con tutti i vantaggi che ciò comporta.

La maniera consigliata per rimpiazzare i decadenti blocchi COMMON e BLOCK DATA è proprio attraverso i MODULE.

La regola aurea è di mettere uno e non più di un modulo per file sorgente.

PROGRAM rete_oss
USE stazioni
IMPLICIT NONE

CHARACTER (LEN=20), rnome
REAL :: rlon, rlat, rt

DO WHILE(.TRUE.)
  READ*, rnome, rlon, rlat, rt
  IF (rlon < -361.) EXIT
  CALL aggiungi_staz(rnome, rlon, rlat, rt)
ENDDO

PRINT'(A,I3,A)','Ho letto ',nstaz,' stazioni'
CALL elabora_temp()

END PROGRAM rete_oss
MODULE stazioni
IMPLICIT NONE

INTEGER, PARAMETER :: nstazmax=100
INTEGER :: nstaz = 0
REAL :: lon(nstazmax), lat(nstazmax), t(nstazmax)
CHARACTER (LEN=20) :: nome(nstazmax)

CONTAINS

SUBROUTINE aggiungi_staz(nnome, nlon, nlat, nt)
CHARACTER (LEN=*), INTENT(IN) :: nnome
REAL, INTENT(IN) :: nlon, nlat, nt

IF (nstaz < nstazmax) THEN
  nstaz = nstaz + 1
  nome(nstaz) = nnome
  lon(nstaz) = nlon
  lat(nstaz) = nlat
  t(nstaz) = nt
ELSE
  PRINT*,'Raggiunto il massimo delle stazioni'
ENDIF

END SUBROUTINE aggiungi_staz

SUBROUTINE stampa_anag()
INTEGER :: i

DO i = 1, nstaz
  PRINT'(A,2F7.2)',TRIM(nome(i)),lon(i),lat(i)
ENDDO

END SUBROUTINE stampa_anag

SUBROUTINE elabora_temp()

IF (nstaz > 0) THEN
  PRINT'(A,F9.2)','Temperatura media:', SUM(t(1:nstaz))/nstaz
ENDIF

END SUBROUTINE elabora_temp

END MODULE stazioni