Tipi derivati: definizione e uso

In F90 è finalmente possibile in maniera ufficiale definire i cosiddetti "tipi definiti dall'utente" (detti anche tipi derivati o strutture), cioè predefinite collezioni di variabili di tipi diversi che possono essere trattate sia come un'entità unica che come variabili singole.

La dichiarazione di un nuovo tipo consiste nell'elenco delle dichiarazioni delle variabili appartenenti al tipo in questione, racchiuse tra TYPE <nometipo> e END TYPE <nometipo>.

La dichiarazione di una variabile di tale tipo si fa invece con il costrutto TYPE(<nometipo>) :: <nomevar>, con la condizione che la dichiarazione del TYPE stesso sia nota ("nello scope") dell'unità di programma corrente direttamente o attraverso lo USE di un MODULE; attributi quali DIMENSION(:), POINTER, SAVE, ecc. possono essere specificati nella dichiarazione, al pari di una variabile ordinaria.

La definizione di un tipo derivato si può fare invece con il cosiddetto costruttore del tipo, cioè una funzione (automaticamente definita) che ha il nome del tipo stesso e riceve un numero opportuno di argomenti corrispondenti nell'ordine ai membri del tipo stesso.

L'accesso ai membri di un tipo derivato si fa aggiungendo, al nome della variabile del tipo in questione, l'operatore % e il nome del membro che interessa. È consentito l'input e l'output di intere variabili di tipi derivati e l'assegnazione di intere variabili di tipo derivato, ma non sono defiite su di esse le ordinarie operazioni aritmetiche, logiche o carattere

È possibile comunque effettuare, definendo opportune INTERFACE, il cosiddetto overloading degli operatori intrinseci fortran per poter estendere in maniera arbitraria le operazioni a cui siamo abituati, ad es. quelle aritmetiche, anche a qualsivoglia tipo derivato.

PROGRAM stazioni

TYPE geo_coord
  REAL :: x, y
END TYPE geo_coord

TYPE staz
  TYPE(geo_coord) :: coord
  CHARACTER (LEN=10) :: nome
  INTEGER :: ora
  REAL :: t, td, rh
END TYPE staz

TYPE(staz) :: oss(20), miss = staz(geo_coord(-1000., -1000.), &
 ' ', 0, 0., 0., 0.)

INTEGER :: i

oss(:) = miss

DO i = 1, 20
  READ(10,*)oss(i)%coord
  CALL get_obs(oss(i)%coord%x, oss(i)%coord%y, oss(i)%ora, oss(i)%t, oss(i)%td)
  oss(i)%rh = relhum(oss(i)%t, oss(i)%td)
ENDDO

WRITE(20,*)oss

END PROGRAM stazioni

Attenzione, esistono delle estensioni non standard al Fortran 77 per gestire i tipi derivati (denominate in genere "record") che hanno un sintassi diversa da quella descritta e sono assolutamente da evitare perché non supportate dallo standard F90.