Sei sulla pagina 1di 35

APPUNTIDELCORSODI

LABORATORIODICALCOLO
AVANZATO
ConcettifondamentalidiFORTRAN90



MARCOLIMONGI
IstitutoNazionalediAstrofisica OsservatorioAstronomicodiRoma


1. CONCETTIFONDAMENTALIDIFORTRAN90

Sviluppareunprogrammainfortranimplicaiseguentitrepassi:

Scrivere il sorgente. Cioe, attraverso un editor di testo, scrivere un file ascii


checontengatutteleistruzionidaeseguire
Compilare.Cioetrasformareleistruzioniinlinguaggiomacchina
EseguireilProgramma.

Lasequenzadicomandidadigitareinambientebashe:

$emacs programma.f90 &(editingdelprogramma)

$ifort [eventuali opzioni] programma.f90(compilazionedelprogramma)

$./a.out (esecuzionedelprogramma)

oppure
$ifort [eventuali opzioni] programma.f90 o eseguibile

$./eseguibile

1.1. StrutturadiunprogrammainFortran

UnprogrammaFortranhageneralmentelaseguentestruttura:

Sezione dichiarativa: che include il nome del programma (o della routine, o


dellafunzione),iltipoeilnomedellevariabiliutilizzate.
Sezione esecutiva: che include le istruzioni che descrivono le azioni che il
programmadevecompiere.
Sezione conclusiva: che e la dichiarazione di fine del programma (o della
routine,odellafunzione)

Program nomeprogramma
! SEZIONE DICHIARATIVA
Implicit none
....dichiarazioni di variabili
:
! SEZONE ESECUTIVA
....istruzioni
! SEZIONE CONCLUSIVA
End Program

1.2. Sezionedichiarativa

La sezione dichiarativa e la prima parte del programma e consiste in una serie di


dichiarazioni(odefinizioni)preliminari.

1.2.1. Tipisempliciintrinseci.

Ilfortran90metteadisposizione5tipididatiintrinseci:

- INTEGERtiponumericopergliinteri
- REALtiponumericoperireali
- COMPLEX tiponumericoperinumericomplessi(nontrattatoinquesto
corso)
- LOGICALtipoperlagestionedeivalorilogici
- CHARACTERtipoperlarappresentazionedistringhedicaratteri

1.2.2. Variabili.

Le variabili nella sezione dichiarativa vengono definite attraverso le istruzioni di


dichiarazione.Ladichiarazioneassociaadunadeterminatavariabileundeterminato
tipo, che ne definisce le caratteristiche. Per ogni tipo si avra in generale una
dichiarazionedifferente.

Tipo INTEGER. Questo tipo puo utilizzare 1, 2, 4 o 8 bytes. Lintervallo di


definizione dipendera dal numeri di bytes utilizzati. Percio la sintassi per la
dichiarazionediunavariabileinterasara:

- INTEGER(KIND=1) :: variabile (1byte,valorida27a271)


- INTEGER(KIND=2) :: variabile (2bytes,valorida215a2151)
- INTEGER(KIND=4) :: variabile (4bytes,valorida231a2311)
- INTEGER(KIND=8) :: variabile (8bytes,valorida263a2631)

TipoREAL.Questotipopuoutilizzare4,8,o16bytes.Lintervallodidefinizioneela
precisione dipendera dal numeri di bytes utilizzati. Percio la sintassi per la
dichiarazionediunavariabilerealesara:

- REAL(KIND=4) :: variabile (4bytes,valorida1038a1038circain


modulo,precisione8cifredecimali)
- REAL(KIND=8) :: variabile (8bytes,valorida10323a10308circa
inmodulo,precisione16cifredecimali)
- REAL(KIND=16) :: variabile (16bytes,valorida104966a104932
circainmodulo,precisione32cifredecimali)

Tipo LOGICAL. Questo tipo e utilizzato per rappresentare i valori logici VERO o
FALSO.Ingeneralequestotipopuoutilizzare,comegliinteri,1,2,4o8bytes.La
sintassiperladichiarazionediunavariabileditipologicoe:

- LOGICAL(KIND=1) :: variabile (1byte)


- LOGICAL(KIND=2) :: variabile (2bytes)
- LOGICAL(KIND=4) :: variabile (4bytes)
- LOGICAL(KIND=8) :: variabile (8bytes)

Tipicamentesiutilizzaladichiarazionecon1byte.

TipoCHARACTER.Questotipoeutilizzatoperrappresentaresequenzedicaratteri
(stringhe)elasintassigeneraleperladichiarazionedivariabilistringhee:

- CHARACTER(LEN=n) :: variabile (n=numerodicaratteri)

1.2.3. Costanti

Le costanti possono essere utilizzate sia nella sezione dichiarativa che in quella
esecutiva.Seutilizzatenellasezionedichiarativalasintassigeneralesara

- TIPO(KIND=n),PARAMETER :: costante=valore

dove, al solito, il tipo e uno di quelli definito sopra. Se, invece, le costanti sono
utilizzatenellasezioneesecutiva,alloraillorotiposaradefinitoimplicitamente.Ad
esempio:

0, +28, -8540 CostantiditipoINTEGER


0.E0, -3.3E2,1.0E-2 CostantiditipoREAL(KIND=4)
0.D0, -3.3D2,1.0D-2 CostantiditipoREAL(KIND=8)
.TRUE., .FALSE. CostantiditipoLOGICAL
ciao, ciao CostantiditipoCHARACTER

1.2.4. Vettori.

Un vettore (a array) e una sequenza di variabili tutte dello stesso tipo. Queste
variabilivengonomemorizzateinposizionicontiguedimemoria.Sipuoaccederead
unadiquestevariabilidirettamentetramiteunindice(opiuingeneraleunanupla
di indici). La dichiarazione di un vettore avviene aggiungendo al nome tipo la sua
dimensione.

- TIPO(KIND=n,LEN=n),DIMENSION(m) :: nome

dovem deveessereuninterocostanteounacostantedefinitacomeparameter.Ad
esempio:

REAL(KIND=8),DIMENSION(3) :: a

dichiaraunvettoredi3reali,accessibilisingolarmentecomea(1), a(2), a(3)

Gliarraypossonoaverepiuindici(dimensioni).Ilrangodiunarrayeilnumerodi
dimensionidellarraystesso.Adesempio

REAL(KIND=8),DIMENSION(4,6) :: b

dichiara una matrice 4x6 i cui elementi sono accessibili singolarmente come
a(i,j).

Gli indici degli array possono avere diversi valori di minimo e massimo. Percio la
dichiarazionepiugeneralediunarraye:

- TIPO(KIND=n,LEN=n),DIMENSION([estremo_inferiore:]estr
emo_superiore) :: nome

Adesempio.

INTEGER(KIND=4),DIMENSION(4:10) :: b

definisceunvettoreblecuicompenentivannodab(4)ab(10).

Comelealtrevariabiliunarraypuoessereinizializzatonellasezionedichiarativa.Ad
esempio:

REAL(KIND=8),DIMENSION(3) :: forza=(/3.2d0,-1.7d0,0.5d0/)

N.B. Il numero di elementi fra i delimitatori / deve coincidere con quello degli
elementidellarray.

Epossibiledefinirearraylacuidimensioneeallocatadinamicamente,cioedurante
lesecuzione. Lo spazio viene allocato solo quando viene incontrata listruzione
ALLOCATE.LafunzioneALLOCATEDinformaselarrayestatoallocatoomeno.La
funzione DEALLOCATE libera lo spazio allocato per larray. Per utilizzare queste
funzioni,larraydeveesseredefinitocomALLOCATABLE,cioe:

- TIPO(KIND=n,LEN=n),ALLOCATABLE,DIMENSION(:) :: nome

oanchepiusemplicemente

- TIPO(KIND=n,LEN=n),ALLOCATABLE :: nome(:)

Percioleistruzioni:

REAL(KIND=4),ALLOCATABLE :: b(:)

REAL(KIND=4),ALLOCATABLE :: a(:,:)

dichiarano rispettivamente un vettore b e una matrice a di dimensioni indefinite.


Perlallocazioneeladeallocazionedinamicadellamemoriadegliarrayrimandiamo
alparagrafosullasezionedichiarativa.

1.2.5. Blocchidimemoriaetichettati.

I blocchi di memoria etichettati, cioe provvisti di nomi, vengono definiti da una


istruzionedispecificazionenellasezionedichiarativadelprogrammacheassumela
formagenerica

- COMMON /nome/nlista

dove nome e il nome globale del blocco COMMON e nlista e la lista dei nomi
dellevariabiliedeinomideivettorichesononellareadimemoriaetichettatanome
separati dalla virgola. A questa area di memoria puo accedere qualsiasi unita o
sottoprogramma(vedidopo)delprogrammaprincipalesemplicementeinserendola
stessaistruzioneCOMMONepreservandolordinedellevariabili.Undisallineamento
dellevariabiliprovocheraunerroreincompilazione.Ovviamenteunavariabilepuo
compariresoloinunCOMMONallinternodellostessoprogramma,sottoprogramma
ounita.SeinunCOMMONcompareunvettore,lasuadimensionenonpuoessere
allocatadinamicamentemadeveesserespecificata.

1.2.6. Definizionedeivaloriiniziali.

Listruzione DATA assegna un valore iniziale ad una variabile prima che il


programma entri nella parte esecutiva. Questa istruzione, quindi, si trova nella
sezionedichiarativadelprogramma.LasintassidellistruzioneDATAelaseguente:

- DATA nlist1/clist1/,nlist2/clist2/....

dove nlist e una lista di nomi di variabili e clist e un elenco di costanti.


Leffettodiquestaistruzione,quindi,equellodiassicurarecheognivariabiledella
listaabbiaunassegnatovaloreinizialespecificatodallacorrispondentecostante.Ad
esempiolistruzione:

DATA A/0.1d0/,B/0.2d0/,N/3/

daraalle variabiliA eB (reali) ivalori iniziali 0.1 e 0.2, e alla variabile N (intera) il
valoreiniziale3.

1.3. Sezioneesecutiva.

Lasezioneesecutivaecostituitadaunaseriediistruzioni.

2.3.1. Espressioni

Le espressioni numeriche sono in generale costituite da operandi numerici ed


operatori numerici. Il risultato di una espressione numerica e generalmente un
singolovalorenumerico.Glioperatorinumericisonoiseguenti:

Operatore Funzione
** Elevamentoapotenza
* Moltiplicazione
/ Divisione
+ Somma
Sottrazione

Le operazioni tra numeri interi hanno come risultato numeri interi. Loperazione
eseguitasulrisultatoeuntroncamento.Cioe:

3/4=0, 4/4=1, 20/4=5, 21/4=5

Leoperazionitranumerirealihannocomerisultatonumerireali.Attenzione,pero,
numerorealenonvuoldireappartenenteaduncontinuo.Ingeneraleilrisultatodi
unaoperazioneeunaapprossimazione.Cioe

3.E0/4.E0=0.75E0, 4.E0/4.E0=1.E0, 1.E0+1.E-16=1.E0

In operazioni miste tra reali ed interi i numeri interi vengono convertiti in reali.
Attenzioneperochelaconversioneavvieneinognisingolosottocalcolo.

1.E0+1/4=1.E0, 1.E0+1.E0/4=1.25E0

Leespressionirelazionaliconsistonoindue(opiu)espressioniicuivalorivengono
confrontati tra loro per valutare se e verificata o meno la relazione stabilita
dalloperatorerelazionale.Glioperatorirelazionisono:

Operatore Relazione
< Minoredi
<= Minorediougualea
== Ugualea
/= Diversoda
> Maggioredi
>= Maggiorediougualea

Il risultato dellespressione relazionale sara .TRUE. o .FALSE. se la relazione


specificatadalloperatorerelazionalesarasoddisfattaomeno.

Le espressioni logiche consistono in uno o piu operatori logici e operandi logici,


numericiorelazionali.Glioperatorilogicisono:

Operatore Esempio Relazione


.AND. A .AND. B Lespressioneevera
seAeBsonovere
.OR. A .OR. B Lespressioneevera
seAoB,oentrambe,
sonovere
.EQV. A .EQV. B Lespressioneevera
seAeBsono
entrambevereo
entrambefalse
.NEQV. A .NEQV. B Lespressioneevera
seAoBsonovere,
malespressionee
falsaseentrambeAe
Bsonovere
.NOT. .NOT. A Lespressioneevera
seAefalsa,efalsa
seAevera.

2.3.2. Istruzionidiassegnazione

Ilsimbolo=noneilsimbolodiuguaglianza,madiassegnazione.Ingenerale,quindi,
in una istruzione di assegnazione avremo a sinistra del simbolo = il nome di una
variabile,adestradelsimbolo= unaqualsiasiespressionevalida.

A=100 AssegnaallavariabileAilvalore100

I=I+1 Aggiunge1allavariabileI eassegnailrisultatoallavariabileI

2.3.3. Allocazionedinamica

Comegiadettoinprecedenzaepossibiledefiniredegliarraylacuidimensionenon
e fissata a priori, ma viene stabilita dinamicamente durante lesecuzione del
programma, a seconda delle necessita. Per fare questo, oltre a definire larray di
tipoALLOCATABLE,enecessarioscriverelistruzione

- ALLOCATE(nomevettore(n))

doveneladimensionedelvettore.Perdefinireunintervallodegliindicilistruzione
sara

- ALLOCATE(nomevettore(n1:n2))

doven1en2sonolindiceinferioreesuperioredelvettore,rispettivamente.Sead
essereallocataeunamatrice,alloralistruzionesara:

- ALLOCATE(nomematrice(n1:n2,m1:m2))

La generalizzazione di questo comando a matrici con piu indici e evidente.


Ovviamente i valori degli indici non sono in generale noti al momento della
compilazionemapossonoesseredefinitidurantelesecuzionedelprogramma.

Dopolutilizzoeopportunodeallocarelamemoriaconilcomando

- DEALLOCATE(nomevettore(n))
- DEALLOCATE(nomevettore(n1:n2))
- DEALLOCATE(nomematrice(n1:n2,m1:m2))

Se si vuole verifica lallocazione di un vettore (o una matrice) si puo utilizzare il


comando:

- ALLOCATED(nomevettore(n))

cherestituisceunvalorelogico.TRUE.seilvettoreestatoallocatoo.FALSE.
veceversa. Lallocazione dinamica della memoria e utile allorquando non si
conoscano le taglie degli array al momento della compilazione. In questo modo,
quindi, e possibile gestire la memoria con maggiore efficenza, consentendo di
ottimizare la quantita di spazio richiesto per il programma e permettendo cosi di
poter trattare problemi altrimenti non trattabili a causa della scarsita della
memoria.

2.3.4. CostruttoIFTHENELSE

Perimplementarealgoritmicomplessiabbiamobisognodiistruzionipiucomplesse.
Laprimadiquestepermettedieffetuaredelledecisioniallinternodelprogramma.
EpossibilequestoattraversoilcostruttoIF-THEN-ELSE.Laformapiusemplice
perquestocostruttoe:

IF(espressione_logica) istruzione

Questo quando listruzione da effettuare e una sola. Se invece si ha un blocco di


istruzioniepossibileutilizzareilcomando:

IF(espressione_logica) THEN

istruzioni

...

...

ENDIF

Notate come sia opportuno (anche se non necessario) che le istruzioni siano
indentate per aumentare la leggibilita del codice. Nel caso ci siano due possiblita
dadecidereilcostruttosipuocomplicarenellaforma:

10

IF(espressione_logica) THEN

istruzioni

...

...

ELSE

istruzioni

...

...

ENDIF

Nelcasoledecisionidaprenderesianopiudiduealloralasintassisara:

IF(espressione_logica) THEN

istruzioni

...

...

ELSEIF(espressione_logica2) THEN

istruzioni

...

...

ELSE

istruzioni

...

...

ENDIF

11

Quindinellaformapiugeneraleilcostruttosara:

IF(espressione_logica_1) THEN

sequenza_di_istruzioni_1

ELSEIF(espressione_logica_2) THEN

sequenza_di_istruzioni_2

ELSE

sequenza_di_istruzioni_3

ENDIF

Epossibileinfineancheassociareunnomealcostruttosecondolasintassi

[nome:] IF(espressione_logica_1) THEN

sequenza_di_istruzioni_1

ELSEIF(espressione_logica_2) THEN [nome]

sequenza_di_istruzioni_2

ELSE [nome]

sequenza_di_istruzioni_3

ENDIF [nome]

dovenomedeveessereunastringalungamassimo31caratteriedeveiniziarecon
una lettere. Nelle clausole ELSE IF e ELSE il nome e opzionale, mentre in
ENDIFeobbligatorio.

12

2.3.5. CostruttoSELECTCASE

Unaltra istruzione di diramazione e il costrutto SELECT CASE la cui sintassi piu


generalee:

[nome:] SELECT CASE(espressione_di_case) THEN

CASE(selettore_1) [nome]

sequenza_di_istruzioni_1

CASE(selettore_2) [nome]

sequenza_di_istruzioni_2

CASE DEFAULT [nome]

sequenza_di_istruzioni_3

END SELECT [nome]

Inquestocasoespressione_di_casevieneconfrontataconiselettori.Un
selettorespecificaunalistadirange:seespressione_di_caseenelrange
di un selettore, allora il blocco di istruzioni corrispondenti verra eseguito,
altrimento si passa al selettore successivo e cosi via fino eventualmente ad
eseguire il blocco di istruzion di CASE DEFAULT. Attenzione perche
espressione_di_case deve essere di tipo INTEGER, CHARACTER o
LOGICALmanonditipoREAL.

Unrangepuoesserespecificatocomesegue:

- valore esegueilbloccoseespressione_di_case==valore
- valore: esegueilbloccoseespressione_di_case>=valore
- :valore esegueilbloccoseespressione_di_case<=valore
- val1:val2 esegueilbloccose
val1<=espressione_di_case<=val2

Unesempiodellusodiquestocostruttoeilseguente:

13

INTEGER :: valore

SELECT CASE (valore)

CASE (1,2,3,5,7,11,13)

stampa a terminale Numero primo

CASE (4,6,8:10,12,14:15)

stampa a terminale Numero non primo

CASE (16:)

stampa a terminale Numero troppo grande

CASE DEFAULT

stampa a terminale Errore

END SELECT

QuestocostruttopermetteunamaggiorechiarezzarispettoalcostruttoIF-THEN-
ELSE.

2.3.6. IstruzionidicicloDO

Le istruzioni di ciclo si utilizzano per eseguire compiti ripetitivi fino a che una
determinatacondizionesiverifica.Iciclipossonoesseredeterminati,sesiconosce
esattamente il numero di iterazioni da effettuare, o indeterminati, se il numero di
iterazioni e ignoto a priori ma finito. I primi vengono detti cicli iterativi mentre i
secondicicliwhile.

Neicicliiterativiilnumerodiiterazionienotonelmomentiuncuisiiniziailciclo.E
quindi necessaria una variabile (detta contatore) che funge da inidice del ciclo.
Questa variabile viene inizializzata automaticamente allinizio del ciclo, viene
aggiornataautomaticamenteadogniiterazioneenondeveesseremaicambiatadal
programmatore.Enecessario,inoltrestabiliregliestremi(inizialeefinale)delciclo,
che possono essere decisi durante lesecuzione e una volta stabiliti non possono
essere piu cambiati, ed eventualmente un incremento che anchesso puo essere
definito durante lesecuzione del programma e una volta stabilito non puo essere
piucambiato.Lasintassigeneralediuncicloiterativoe:
14

DO indice=inizio,fine[,incremento]

sequenza di istruzioni

END DO

Nelcasopiusempliceincuilincrementoeugualea1avvengonoimplicitamentele
seguenticose:

1. Immediatamente prima del DO viene posto indice=inizio (cio


avvieneunasolavolta.
2. Se indice<=fine allora viene eseguita la sequenza di
istruzioni. Immediatamente prima di END DO viene posto
indice=indice+1.
3. Altrimentisiescedalciclo

Inquestocasoilnumerodiiterazionitotalisarafine-inizio+1.

Lestensionealcasoincuilincrementosiaarbitrarioe

1. Immediatamente prima del DO viene posto indice=inizio (cio


avvieneunasolavolta.
2. Se indiceincremento<=fineincremento allora viene eseguita
la sequenza di istruzioni. Immediatamente prima di END DO
vienepostoindice=indice+incremento.
3. Altrimentisiescedalciclo

In questo caso il numero di iterazioni totali sara (fine-


inizio+incremento)/incremento.

Neicicliiterativi,quindi,ilnumerodiiterazionidaeseguireenotoalmomento in
cui si entra nel ciclo. La limitazione di questi cicli, pero, sta nel fatto che esistono
problemichenonsipossonorisolvereconunnumerodiiterazionidefinitoapriori.
Ad esempio la lettura da tastiera di una sequenza di interi terminata da uno 0, il
calcolo della lunghezza della sequenza (senza lo 0) e la stampa a terminale di
questultima.Questalimitazionepuoesseresuperataconicicliwhile.

Nei cicli while il numero di iterazioni non e necessariamente noto al momento di


iniziareleiterazioni.Lasintassigeneralediunciclowhileelaseguente:

15

DO

sequenza_di_istruzioni_1

IF(espressione_logica) EXIT

sequenza_di_istruzioni_2

END DO

Sialaprimachelasecondasequenzadiistruzionipossonoesserevuote(ovviamente
non contemporaneamente). Lespressione_logica e la sentinella del ciclo e
rappresenta un evento particolare (ad esempio un valore particolare di una
variabile) per cui il ciclo deve essere interrotto. Listruzione EXIT, percio,
determinaluscitadalciclo.Neicicliannidatiquestaistruzionehaeffettosempresul
ciclopiuinterno.Percioinquestasequenza

DO

sequenza_di_istruzioni_1

DO

sequenza_di_istruzioni_2

IF(espressione_logica) EXIT

sequenza_di_istruzioni_3

END DO

sequenza_di_istruzioni_4

END DO

listruzioneEXITportaallasequenza_di_istruzioni_4.Notachelitruzione
EXITpuoessereutilizzatainqualsiasitipodiciclo,ancheinquelliiterativi.

Unaltrapossibilitadiimplementazionedeicicliwhileelaseguente:

DO WHILE (condizione)

sequenza_di_istruzioni_1

END DO

Inquestocasoilciclovieneeseguitofinoachelacondizionerisultaverificata.
16

Una istruzione spesso utilizzata allinterno dei cicli (sia iterativi che while) e il
CYCLE, che fa partire la prossima iterazione del ciclo. Se questa istruzione viene
utilizzata nei cicli while, lesecuzione riparte dalla prima sequenza di istruzione del
ciclodopoilDO,seinveceeutilizzatainuncicloiterativo,allorailcontatoreviene
incrementatoelesecuzioneripartedallaprimasequenzadiistruzionisubitodopoil
DO.

DO

sequenza_di_istruzioni_1

IF(espressione_logica) CYCLE

sequenza_di_istruzioni_2

END DO

DO indice=inizio,fine[,incremento]

sequenza_di_istruzioni_1

IF(espressione_logica) CYCLE

sequenza di istruzioni_2

END DO

ComeperlistruzioneEXIT,anchelistruzioneCYCLE,neicicliannidati,haeffetto
sempresulciclopiuinterno.

ComepericostruttiIF-THEN-ELSEeSELECT CASE,ancheiciclipossoessere
identificaticonunnome.Percioingeneralelasintassicompletasara:

[nome:] DO indice=inizio,fine[,incremento]

sequenza di istruzioni

END DO [nome]

17

[nome:] DO

sequenza_di_istruzioni_1

IF(espressione_logica) EXIT [nome]

sequenza_di_istruzioni_2

END DO [nome]

[nome:] DO WHILE (condizione)

sequenza_di_istruzioni_1

END DO [nome]

Lutilizzo del nome e utile spesso per gestire i comandi EXIT e CYCLE nei cicli
annidati.Adesempioinquestasequenzadiistruzioni:

esterno: DO

sequenza_di_istruzioni_1

interno: DO

sequenza_di_istruzioni_2

IF(espressione_logica) EXIT esterno

sequenza_di_istruzioni_3

END DO interno

sequenza_di_istruzioni_4

END DO esterno

sequenza_di_istruzioni_5

ilcomandoEXITnonportaallesecuzionedellasequenza_di_istruzioni_4
come farebbe se non ci fosse indicato il nome, ma porta alluscita del ciclo piu
esternoepercioallesecuzionedellasequenza_di_istruzioni_5.

18

2.3.7. OperazionidiInput/Output

Un programma FORTRAN puo leggere e scrivere su file, cioe una sequenza di


elementi(caratterie/onumeri)memorizzatiinmemoriasecondaria(es.harddisk).
Ladisciplinadiaccessoadunfilepuoesseresequenziale,cioedalprimoelemento
ai successivi in sequenza, o casuale, cioe ad un elemento qualsiasi in qualsiasi
momento. E da notare che questi concetti sono generali ed indipendenti dal
linguaggiodiprogrammazione.

Leoperazioniprincipalisufilesono:

- Aperturadiunfile
- Letturadidati
- Scritturadidati
- Chiusuradelfile

Aprirediunfilesignifcacreareunacorrispondenzatrailnomefisicodelfileedun
nome logico da utilizzare allinterno del programma e si effettua attraverso
listruzione:

- OPEN (lista_open)

Lalista_openeunalistadiparametriseparatidaunavirgola.Iparametrisono:

- UNIT: cheeilnomelogicodautilizzareperaccederealfileallinternodel
programma.Es.UNIT=10
- FILE: cheeilnomefisicodelfile.Es.FILE=pippo.txt
- STATUS: chepuoassumereiseguentivalori:
- OLD: se il file esiste gia e deve essere solo aperto; se il file non
esistevienesegnalatounerrore.
- NEW:percreareunnuovofilesequestononesiste;seilfileinvecee
giaesistentevienesegnalatounerrore
- REPLACE:seilfileesistevienecancellatoericreato
- SCRATCH:percreareunfiletemporaneochenonvienesalvato
- ACTION:chepuoessereREADoWRITE
READ: il file puo essere solo letto, se viene scritto viene
segnalatounmessaggiodierrore
WRITE: il file puo essere solo scritto, se viene letto viene
segnalatounmessaggiodierror
19

READWRITE:ilfilepuoesseresialettochescritto
- IOSTAT: variabile di tipo INTEGER che memorizza eventi
particolari e che permette di controllare lo stato delle operazioni. La
sintassieIOSTAT=nome_variabile.Se
nome_variabile==0 tuttoeandatoabuonfine
nome_variaible/=0 ce stato un errore nelloperazione
(adesempio,unfileinletturanonesiste,sieraggiuntolafinedi
unfileinletturaolafinediunariga,siesbagliatoilformatodi
lettura,etc.)

Ingenerale,sesivuoleaprireunfileinscritturaesufficientelistruzione

- OPEN (UNIT=10,FILE=pippo.txt,IOSTAT=ierr)

cioesieassegnatoalfilenuovopippo.txtilnomelogico10elavariabileintera
ierrcontieneilrisultatodelleoperazionisuquestofile.Attenzionepercheseilfile
esistequestovienecancellatoericreato.

Lachiusuradiunfilesignificacancellarelaccoppiamentotrailnomefisicodelfilee
lunitalogicacreataallinternodelprogramma.Lasintassidelcomandoe:

- CLOSE (UNIT=unita_logica)

Seunfileapertononvienechiuso,lachiusuraavvieneinmodoimplicitoaltermine
delprogramma.

Laletturaelascritturasufileavvengonoattraversoicomandi

- READ (UNIT=unita_logica,formato,IOSTAT=variabile)
- WRITE (UNIT=unita_logica,formato)

dove appunto lunita_logica e il nome logico assegnato al file nel comando


OPEN.Laspecificadiformatoverradescrittonelparagrafosuccessivo.

Altreoperazionichepossiamofaresuifilessono:

- REWIND checiriposizionaalliniziodelfile
- BACKSPACE checiriposizionaallalineaprecedente

Sealpostodellunitalogicasiscriveunasterisco,alloraquestoindicaunaletturao
scritturadallinputolouptutstandard,tipicamenteilmonitor.

20

2.3.8. FormattazionedellInputeOutput

Abbiamovistonelparagrafoprecedentecheallaletturaeallascritturasufileosu
monitorpuoessereassociataunaspecificadiformato.Laspecificadiformatopuo
essereassegnataattraverso:

- uninterochespecificaletichettadiunaistruzioneFORMATesplicita.Ades.

write(*,100)a

100 FORMAT(decrittori_di_formato)

dove100eletichettadiformato;

- unastringacostanteconnome
formato=(descrittori_di_formato)

write(*,formato)a

- unastringacostantesenzanome
write(*,FMT=(descrittori_di_formato))a
- unastringavariabile(usosofisticatochenontratteremoinquestocorso)

In tutti i casi i descrittori_di_formato specificano completamente il


formato.Inparticolare:

Controllanolaposizioneverticaledellariga
Controllanolaposizioneorizzontale
Specificanocomestampareunadeterminatovalore
Specificanoquantevoltedeveessereripetutoundescrittore

Idescrittoridiformatoutilizzanoiseguentisimboli:

- c:numerodicolonna
- d:numerodicifreadestradelpuntodecimale
- m:numerominimodicifredavisualizzare
- n:numerodispazidasaltare
- r:fattorediripetizione
- w:quanticaratteriutilizzareperundatovalore

Sealpostodellaspecificadiformatoceunasterisco,allorasiintendeunformato
libero,cioesenzaformattazione.
21

NumeriInteri:Ildescrittorediformatogeneraleperinumeriinterihalaforma

- rIw.m:
- rindicaquantovolteapplicareildescrittore
- windicaquanticaratteriusareperilnumero
- mindicaquantecifremostrare

Ecco alcuni esempi:

NumeriReali:Ildescrittorediformatogeneraleperinumerirealihalaforma

- rFw.d (formatononesponenzialeovirgolafissa):
- rindicaquantovolteapplicareildescrittore
- windicaquanticaratteriusareperilnumero
- dindicaquantecifredecimaliusaredopoilpunto
- rEw.d (formatoesponenzialeovirgolamobile):
- rindicaquantovolteapplicareildescrittore
- windicaquanticaratteriusareperilnumero
- dindicaquantecifredecimaliusaredopoilpunto

Notabene,seildescrittorediformatoeprecedutoda1Pallorailprimocarattere
delnumeroelaprimacifrasignificativa.

22

Alcuniesempi:

WRITE(*,FMT=(E12.4))0.153 0.1530E+00

XXXXXXXXXXXX

WRITE(*,FMT=(1P,E12.4))0.153 1.5300E-01

XXXXXXXXXXXX

WRITE(*,FMT=(F8.4))0.153 0.1530

XXXXXXXX

Stringhe:Ildescrittorediformatogeneraleperlestringhehalaforma:

- rAw:
- rindicaquantovolteapplicareildescrittore
- w(opzionale)specificalalarghezzadelcampo

Alcuniesempi:

WRITE(*,FMT=(A6))pippo pippo

XXXXXX

WRITE(*,FMT=(A8))pippo pippo

XXXXXXXXX

1.4. SezioneConclusiva

Lasezioneconclusivaecompostadalcomando:

- END [PROGRAM [nome_programma]]

23

1.5. Modularizzazione(Subroutine,Function,Module)

La modularizzazione e unesigenza generale della programmazione. Essa e utile a


chi utilizza moduli realizzati da altri ed e utile a chi programma moduli per farli
usareadaltri.Unmoduloeunascatolanera.Perutilizzarlo:

bastaconoscerecosafa
nonserveconoscerecomelofa

In questo corso vedremo come realizzare semplici moduli software chiamati


sottoprogrammi.Eragionevolescrivereunsottoprogrammainalmenoduecasi:

unostessocompitodeveessereripetutopiuvolte,incontestidiversi
unostessocompitoeparametrico

InFORTRAN90esistonodietipidiunitadiprogramma:

SUBROUTINE
FUNCTION

LeunitadiprogrammainFORTRAN90possonoesserecontenuteinappositelibrerie
denominatemoduli(MODULE).

FUNCTION, SUBROUTINE e MODULE possono essere allinterno dello stesso file


che contiene il programma principale oppure possono essere file a se stanti (con
estensione.f90).Inquestosecondocasodevonoesserecompilateseparatamentee
successivamentecollegatealprogrammaprincipale.

Supponiamodiavereiseguentifilesorgenti:

princ.f90(contieneilPROGRAMmainoprogrammaprincipale)
miomod.f90(contieneunMODULEmodulo)
miasub.f90(contienelaSUBROUTINEstampe)
miafunc.f90(contienelaFUNCTIONareacerchio)

Lasequenzadicomandipercreareedutilizzareilfileeseguibileelaseguente:

Compilazioneseparatadeisingolifiles:
$ifort c princ.f90 risultato: file princ.o
$ifort c miomod.f90 risultato: file miomod.o e
modulo.mod

24

$ifort c miasub.f90 risultato: file miasub.o


$ifort c miafunc.f90 risultato: file miafunc.o

Collegamento(link)deisingolifilesecreazioneeseguibile:
$ifort o prova princ.o miomod.o miasub.o miafun.o
risultato file eseguibile prova

Esecuzionefileeseguibile:
$./prova

Percioingeneralelosviluppodiprogrammiprevedelasituazionetipicaincuisiha:

Unfilesorgente(.f90)contenteilPROGRAM(oprogrammaprincipale)
vari files sorgente (.f90) ogniuno contente un MODULE; ogni MODULE puo
contenerevarieSUBROUTINEe/oFUNCTION;
vari files sorgente (.f90) contenenti una o piu SUBROUTINE e una o piu
FUNCTION

Ogni unita di programma sara cotituita, come il programma principale, da una


sezionedichiarativa,unasezioneesecutivaedunasezioneconclusivaeperqueste
varranno le stesse regole discusse per il programma principale. Andiamo a vedere
piuindettagliolevarieunitadiprogramma.

2.5.1. SUBROUTINE

Unasubroutineeunaunitadiprogrammaindipendenteche

puoessereutilizzataallinternodialtriprogrammi
accettauncertonumerodiparametriininputchepuoelaborare
restituisceuncetronumeroparametriinoutput

Lasintassiperladichiarazionediunasubroutineelaseguente:

25

SUBROUTINE nome_subroutine(lista_argomenti)

sezione dichiarativa

sezione esecutiva

RETURN

END SUBROUTINE nome_subroutine

Nelladichiarazionedellasubroutine,lalista_argomentieunalistadi
parametrichepossonoessereininpute/ooutput.

Perinvocareunasubroutineenecessarioutilizzarelistruzione

CALL nome_subroutine(lista_argomenti)

Listruzione RETURN a fine procedura e opzionale, tuttavia alcuni compilatori


potrebberorichiederlaobbligatoriamente.

2.5.2. MODULE

Il Module e ununita di programma che permette di includere subroutine e


funzionialsuointerno.Lasintassiperladichiarazionediunmoduloe:

MODULE nome_modulo

CONTAINS

sezione dichiarativa

dichiarazioni_di_unita_di_sottoprogrammi

END MODULE nome_modulo

Perinvocareisottoprogrammioutilizzareledefinizioniditipocontenutinelmodulo
enecessarioimportareilmoduloattraversolistruzioneUSE.Ades.

PROGRAM nome_programma

USE nome_modulo

IMPLICIT NONE

.....
26

2.5.3. FUNCTION

Le funzioni definite dallutente possono essere utilizzate come qualsiasi funzione


implicitaFORTRAN90.Lasintassiperdefinireunafunzionee:

FUNCTION nome_function(lista argomenti)

! sezione dichiarativa

TIPO:: nome_function

! sezione esecutiva

...

nome_function=espressione

RETURN

END FUNCTION [nome_function]

Oinmanieraequivalente:

TIPO FUNCTION nome_function(lista argomenti)

Come nel caso delle subroutine anche in questo caso listruzione RETURN e
opzionale.Ledifferenzeprincipalitrasubrotuineefunctionsonoleseguenti.

Lefunctionrestituisconounvalore
Iltipoditalevalorevaopportunamentedichiarato
Lefunctionvengonochiamateallinternodelleespressioni
NellinvocazionediunafunctionnonvausatalistruzioneCALL

2.5.4. Regoledivisibilita

Lecostanti/variabilidichiarateinunaunitadiprogrammasichiamanoLOCALIenon
sono visibili allesterno dellunita di sottoprogramma stessa. Analogamente, le
costanti/variabilidefinitenelprogrammaprincipalenonsonovisibiliallinternodelle
varieunitadiprogramma.Diconseguenzapossiamodichiararecostantie/ovariabili
con lo stesso nome in vari sottoprogrammi senza paura che ci sia interferenza tra
queste.

27

2.5.5. Passaggiodeiparametrineisottoprogrammi

Iparametricostituisconolinterfacciadiunaunitadiprogramma,ovveroidatiche
occorrono per poterla utilizzare. La lista dei parametri, presente tra le parentesi
tondeafiancoalnomedellunitadiprogramma,ecostituitaingeneraledavariabili
e/oarray.IparametrideisottoprogrammiFORTRAN90sonodettiargomentifittizi,
cioesonodeisegnapostoperivaloriverieproprichesarannoutilizzatidurante
lesecuzione del programma (argomenti reali). Esistono tre modalita distinte per
ogni parametro passato che si definiscono attraverso lattributo INTENT nei
seguentimodi:

INTENT(IN):ingresso.Il parametronon puo essere modificato dentro la


subroutineofunzione
INTENT(OUT):uscita.Altermine della subroutine o funzione il valoredel
parametro potra essere stato modifica, il valore in ingresso non sara
utilizzato
INTENT(INOUT): ingresso e uscita. Il parametro ha informazioni in
ingressomapotraesseremodificato(DEFAULT).

Quando si invoca un sottoprogramma e necessario istanziare tutti i parametri,


sostituendo cioe ai parametri fittizi i valori effettivi (espressioni, variabili, array,
costanti).LoschemadipassaggiodeivaloriutilizzatodalFORTRAN90equelloper
riferimento,nonvengonopassatiivaloriverieproprimavienepassoilriferimento
allalocazionedimemoriachecontieneilvalore.

28

2.6. Diagrammidiflusso

Per sviluppare programmi complessi e utile avvalersi dei cosi detti diagrammi di
flusso che sono una rappresentazione grafica delle operazioni che il programma
dovraeseguirepereffettuareilcompitochenoidesideriamo.Lanotazionegrafica
deidiagrammidiflussoeriportatanellaseguentefigura:

Unesempiodidiagrammidiflussodiunprogrammaeilseguente:

29

2.6.1. DiagrammadiflussodelcostruttoIFTHENELSE

Sullabasedelledefinizioniprecedentipossiamoindicareildiagrammadiflussodiun
costruttoIF-THEN-ELSEchesara:


Ad esempio se volessimo scrivere un programma che, acquisiti in ingresso due
numeriaebdeterminilasoluzionedellequazioneax+b=0elastampiaterminale,
avremmoilseguentediagrammadiflusso:

30

2.6.2. DiagrammadiflussodelcostruttoSELECTCASE

AnalogamenteildiagrammadiflussodiuncostruttoSELECT CASEsara:

31

2.6.2.DiagrammadiflussodelcicloDO

Ildiagrammadiflussodiuncicloiterativoe:


Un esempio di implementazione di un ciclo iterativo in un programma piu
complessoe:

32


Ildiagrammadiflussoperunciclowhile,invece,halaforma:

33

34