Sei sulla pagina 1di 39

CORSO DI FORTRAN M.

Viviani
(attenzione: versione in corso di preparazione!!!!)

Parte A. Introduzione al FORTRAN.


1 Sistemi di numerazione 2 La rappresentazione dei numeri nel Fortran 3 Le costanti 4 Le variabili 5 Assegnazione 6 Espressioni aritmetiche

Parte B. I principali Parte C. La struttura comandi del dei programmi FORTRAN. FORTRAN.
7 Un esempio di programma 8 La definizione delle variabili 9 Le istruzioni di scrittura e lettura 10 L'istruzione DO 11 Decisioni 12 L'istruzione GOTO e i loop "condizionali" 13 Il programma principale e i sottoprogrammi 14 Variabili globali

Parte A. Introduzione al FORTRAN.

1 Sistemi di numerazione L'unit elementare di informazione nei computer pu assumere solo due valori,

simbolicamente definiti come 0 ed 1. Questa unit chiamata bit (da "binary digit"); 8 bits formano il byte. Tutti i dati presenti nella memoria del computer saranno rappresentati da un sistema numerico a base 2 (sistema binario). Qui non ci dilungheremo sull'uso dei sistemi di numerazione differenti da quello decimale ma ricordiamo solamente che un numero di m cifre x1x2...xm rappresentato nel sistema con base b equivale a x1 bm-1 + x2 bm-2+ ... + xm b0 , quindi, per esempio, il numero 10011 in notazione decimale diventa 1 24 + 1 21 +1 20 = 19. Un altro sistema utile quello esadecimale, cio in base 16; Le cifre di questo sistema sono
0 1 2 3 4 5 6 7 8 9 A B C D E F.

Per esempio, FF in notazione esadecimale diventa 15 161 + 15 160 = 255 in notazione decimale.
[HOME]

2 La rappresentazione dei numeri nel Fortran Nel fortran i numeri sono considerati avere un numero fisso di bytes; il primo bit rappresenta il segno del numero:0 +, mentre 1 -. 2.1 numeri interi I numeri interi sono l'esatta traslazione del numero binario nell'equivalente in base decimale. Possono essere di due tipi: - tipo I2, lunghi due bytes: il primo bit , come gi stato detto, utilizzato per il segno, mentre gli altri 15 bits danno il valore del numero; quindi in questa maniera si possono avere numeri n compresi fra -(215-1) e 215-1, |n|< 215-1=32 767 3 105; - tipo I4, lunghi 4 bytes; in questo caso |n|< 231-1=2 147 483 647 2 109. In pratica, questo intervallo di valori finito con cui si deve lavorare pu provocare dei problemi. Se per esempio, con un operazione si "esce" dall'intervallo consentito, il risultato finale sar non corretto. 2.2 numeri reali Per considerare numeri che possano avere virgola mobile ("floating point") e un intervallo di valori pi esteso, si scompone il numero in una frazione compresa fra 0 ed 1 (mantissa), moltiplicata per una potenza di 10 elevata ad un certo esponente (in pratica, il computer usa

2 come base della potenza). Si possono avere 3 tipi di numeri reali: - tipo R4 (anche chiamati a precisione singola, SINGLE PRECISION), lunghi 4 bytes. Il primo byte viene utilizzato per l'esponente, quindi avendo a disposizione 8 bits, si possono avere al massimo 28 = 256 diversi esponenti; di questi la met viene utilizzata per gli esponenti positivi (0127) e l'altra met per gli esponenti negativi (-1 -128), per cui la massima e la minima grandezza dei numeri che si potr rappresentare sono, rispettivamente, 2127 1038 e 2-128 10-39. Per quanto riguarda la mantissa, si hanno a disposizione 23 bits (1 si usa per il segno), quindi 223-1= 8389607 numeri; dunque, i numeri a precisione singola possono avere al massimo 7 cifre decimali (in qualche caso 6). Per esempio, 1/3 0.333 333 3 100 , 2/3 0.666 666 7 100 . Ricapitolando , R4: precisione 7 cifre decimali, numero max: 1038, numero min: 10-39. - tipo R8 (anche chiamati a precisione doppia, DOUBLE PRECISION), lunghi 8 bytes. Il computer utilizza 11 bits per l'esponente, quindi si hanno a disposizione 211 = 2048 valori, di cui circa la met viene utilizzata per gli esponenti positivi ( 21024 10308) e l?altra met per quelli negativi (2-1024 10-308). Per la mantissa, si hanno 53 bits che permettono di avere 15 cifre significative. Ricapitolando: R8: precisione 15 cifre decimali, numero max: 10308, numero min: 10-308. Da notare che questi dati possono essere diversi da computer a computer. - tipo R16 (anche chiamati a precisione quadrupla, QUADRUPLE PRECISION), lunghi 16 bytes. Tutti i nuovi bits si usano per la mantissa, quindi, si ha: R16: precisione 32 cifre decimali, numero max: 10308, numero min: 10-308. Questa rappresentazione ha diverse conseguenze nei calcoli; i pi comuni inconvenienti sono: errore di troncamento: si creano in quanto il computer lavora con numeri decimali a precisione finita, per cui un'operazione eseguita con numeri troncati pu dare un risultato diverso da quello "giusto".

Esempio 1: esatto: 4/3 + 1/3 = 5/3 0.166 666 7 101

con numeri R4: 0.133 333 3 101 + 0.333 333 3 100 = 0.166 666 6 101

Esempio 2: esatto: 0.4 + .4 10-7 + .4 10-7 = 0.400 000 0 + 0.000 000 04 + 0.000 000 04 = 0.400 000 08 0.400 000 1 con numeri R4: (0.400 000 0 + 0.000 000 04) + 0.000 000 04 = (0.400 000 04 0.400 000 0) + 0.000 000 04 = 0.400 000 0 + 0.000 000 04 = 0.400 000 04 0.400 000 0 . chiaro che dopo un grande numero di operazioni l'errore di arrotondamento crescer e il numero di cifre significative si ridurr pericolosamente. In questo caso conviene usare numeri con un maggior numero di decimali, cio usare la rappresentazione R8 o R16. Da notare che il computer in genere non avverte che si stanno perdendo cifre significative. overflow: questo termine sta a significare che in una operazione si prodotto un numero che pi grande (in valore assoluto) del limite consentito, quindi maggiore di 1038 (10308) per i numeri in precisione singola (doppia e quadrupla). underflow: questo termine sta a significare che in una operazione si prodotto un numero che pi piccolo (in valore assoluto) del limite consentito, quindi minore di 10-39 (10-308) per i numeri in precisione singola (doppia e quadrupla). Generalmente, viene assunto come risultato il valore zero. In questi due ultimi casi, ma questo dipende dal particolare tipo di computer, durante il "run" del programma viene segnalato l'avvenuto overflow ed underflow. In alcuni computers (es. IBM) questa segnalazione non automatica, ma si ottiene dopo avere "caricato" alcuni sottoprogrammi specifici.

2.3 numeri complessi Nel fortran possibile usare anche i numeri complessi in maniera completamente automatica. Per esempio, quando il programma elabora il prodotto di due numeri complessi z1 e z2 trova come risultato il numero complesso la cui parte reale data dal prodotto delle

parti reali meno il prodotto delle parti immaginarie di z1 e z2, ecc. Si possono avere numeri complessi con 8, 16 e 32 bytes, ognuno composto dall'insieme di due numeri reali con 4, 8 e 16 bytes, rispettivamente. Naturalmente, questi due numeri reali rappresentano la parte reale ed immaginaria del numero complesso. Parleremo dunque di numeri complessi di tipo C8 a precisione semplice, C16 a precisione doppia e C32 a precisione quadrupla. [HOME] 3 Le costanti Qualunque numero che compare nelle operazioni di un programma viene detto costante numerica. Nelle costanti intere non compaiono ne' il punto ne' la virgola. Esempi di costanti intere: 1 , 12 , -100 . In una costante reale R4 deve comparire il punto decimale (non la virgola); si pu usare anche la notazione esponenziale, tipo 0.xxx E yy dove E yy sta per 10 elevato a yy, con il segno - obbligatorio ed il segno + facoltativo. Il numero yy deve essere intero e pu essere ad una cifra. Esempi di costanti reali R4: 1. , 1.2 , -10.E-3 . Per una costante in doppia (quadrupla) precisione si deve usare la notazione esponenziale sostituendo pero' al posto della lettera E, la lettera D (Q). Esempi di costanti reali R8: 1.D0 , 1.2D0 , -10.D-3 . Le costanti complesse si indicano invece mettendo la parte reale e la parte immaginaria fra due parentesi tonde, separate da un virgola. La parte reale ed immaginaria, essendo numeri reali, seguono la stessa notazione dei numeri reali R4, R8 ecc. Esempi di costanti complesse C8: (1.,3.) , (1.E-2,4.E3) . Esempi di costanti complesse C16: (1.D0,3.D0) , (1.D-2,4.D3) . [HOME] 4 Le variabili Una variabile specifica la locazione di memoria dove viene immagazzinato un numero. Una variabile indicata da un insieme di lettere e numeri; unica limitazione che il primo carattere deve essere necessariamente una lettera. Esempi validi di variabili: VAR, A12, B1B. Esempi non validi di variabili: 1VAR, 0A12, ]1B, >AA. Inizialmente il programma usa la convenzione: le variabili con lettera compresa fra I,J,K,L,M,N sono intere di tipo I4;

tutte le variabili che iniziano con le altre lettere (A-H,O-Z) sono intese essere di reali di tipo R4 (reali a precisione semplice). [HOME]

5 Assegnazione Per dare un dato valore ad una variabile si usa il comando si assegnazione " =". Vediamo alcuni esempi: 1) I variabile intera (I2 o I4): I=4 2) A variabile reale R4 : A=100. 3) B variabile reale R8: B=1.D2 4) C variabile reale R16: C=1.Q2 5) D variabile complessa C8: D=(20.,3.) oppure D=(2.E1,30.E-1) ecc. Il comando " =" sta a significare di prendere il valore dell'espressione a destra del segno " =" e immagazzinarlo nella locazione di memoria contrassegnata dal nome della variabile a sinistra. Naturalmente, se la variabile di un certo tipo di lunghezza "n" bytes, nella memoria sar giusto assegnato uno spazio di "n" bytes; quindi necessario definire bene (e ricordarsi) di che tipo la variabile. Se si assegna un numero di un certo tipo ad una variabile di un altro tipo, il computer si arrangia come pu; ecco alcuni esempi: 1) I variabile intera:
I=4.9 I=0.1

oppure A=1.E2

ecc.

I assume il valore 4 Iassume il valore 0

2) A variabile reale R4:


A=2 A assume il valore 2. A=2.D2 A assume il valore 200. A=(2.,4.) A assume il valore 2.

3) B variabile reale R8:


B=2 B=0.2

B assume il valore 2.D0 B assume il valore 0.200 000 0xxxxxxxxx

4) C variabile complessa C8 C=2. : C assume il valore (2.,0.) L'errore pi grave viene commesso nel caso 1) in quanto si perde completamente la parte decimale. Nel caso 3) assegnare ad una variabile in doppia precisione un numero in precisione semplice (si usato la notazione con il punto decimale), porta ad un valore dove le cifre decimali dall'ottava alla sedicesima non sono definite e possono assumere valori arbitrari (rappresentati dalle "x"). [HOME] 6 Espressioni aritmetiche Le operazioni di somma, sottrazione, prodotto, divisione ed elevamento a potenza si ottengono semplicemente usando i seguenti operatori:

+ *

somma sottrazione prodotto

divisione

** elevamento a potenza

Questi operatori devono stare necessariamente tra due valori numerici (costanti o variabili). I simboli + e - possono essere usati anche davanti ad un solo numero, per esempio -G rappresenta il numero immagazzinato in G cambiato di segno. Vediamo alcuni esempi:
A=A+1. prendi il valore di A, sommaci uno e rimettilo in A; A=B*C prendi i valore di B e C, moltiplicali e mettili in A; A=B**2 prendi il valore di B, elevalo alla potenza 2 e mettilo in A.

Si possono usare espressioni pi complicate, dove compaiono pi operazioni aritmetiche nella stessa linea; in questo caso diventa importante la priorit delle operazioni, specificata dalla seguente tabella:

operazione ** * / + -

priorit alta media bassa

Esempi:
A=B+C*DA=B+(C D) A=B/C*DA=(B D)/C A=B*C**DA=B CD A=B**C*DA=BC D

Nelle espressioni aritmetiche si possono introdurre le parentesi, in modo da eseguire le operazioni nell' ordine desiderato: come regola, ogni espressione racchiusa da parentesi viene eseguita prima di tutte le altre. Esempi:
A=B**(C+D)A= BC+D A=B/(C+D)A= B/(C+D) A=(B+C*(D+E))*G A= B G + C D E + C E G

Valgono le seguenti regole: 1) operazioni con la stessa priorit vengono eseguite seguendo l'ordine da sinistra a destra. 2) il risultato di una operazione risulta essere dello stesso tipo (intero, reale, ecc.) dei due operandi. 6.1 Nota sulla divisione fra interi Gli operatori +,-,* e ** possono essere usati senza nessuna difficolt anche tra interi, mentre l'operatore / (divisione) comporta alcuni problemi. Per esempio, cosa succede nel calcolo di 4/M se M ha il valore 3? L'espressione si riduce a 4/3= 1.333..., ma siccome per la regola 2 4/M deve essere intero, il risultato finale sar 1. Cos se M=5, il risultato finale 0. Con i numeri interi quindi importante l'ordine delle operazioni: per esempio, se M=5, otteniamo nei vari casi
I=4*M/5+1 5 , I=4/5*M+1 1 (qualunque sia il valore di M).

6.2 Nota sulla assegnazione di variabili intere Abbiamo gi detto che, nell'assegnare ad una variabile intera un valore reale, si tronca (e non si arrotonda) la parte decimale. Questo fatto pu dare risultati non corretti; per esempio, consideriamo questa espressione:

N=P*Q/R , (per convenzione N intera e P, Q, R reali) .

Cosa succede se P=2. , Q=3. , e R=6. ? L?espressione si riduce a 6./6. e quindi N dovrebbe assumere il valore 1. Eppure, il calcolo potrebbe portare (per errori di troncamento) ad il valore di 0.9999999, che 1 in pratica, ma condurrebbe ad attribuire ad N il valore 0. Per evitare questo tipo di incertezze utile modificare l'espressione in
N=P*Q/R +0.001

cio aggiungere una quantit piccola prima del troncamento. 6.3 Nota sulle operazioni contenenti operandi di tipo differente Se in una espressione compaiono costanti e/o variabili di tipo differente (interi, reali, complessi), valgono le seguenti regole: 3) interi e reali: il risultato di una operazione intero se tutti gli operandi sono interi ed reale se almeno uno degli operandi reale; 4) reali R4 e reali R8: il risultato di una operazione reale R4 se tutti gli operandi sono reali R4 ed reale R8 se almeno uno degli operandi reale R8; 5) reali e complessi: il risultato di una operazione reale se tutti gli operandi sono reali ed complesso se almeno uno degli operandi complesso; per esempio, nell'operazione A*B, con A reale R4 e B reale R8, prima si trasforma A in variabile R8 (si aggiungono cifre decimali) e poi si esegue l'operazione che dar come risultato un numero reale R8. Non difficile trovare ulteriori regole per operazioni fra interi e complessi, reali R4 e reali R16, complessi C8 e complessi C16 ecc. ecc. Esempio 1: M=I+4*J/K-A con I=3, J=5 e K=6 interi; A=4.1 reale. L' espressione calcolata nei seguenti passi: 1) calcolo 4*J20 ( operazione di priorit alta pi a sinistra); 2) calcolo 20/K3 (troncamento cifre decimali); 3) I+36 ; 4) 6-A1.9 (il risultato reale); 7) M assume il valore finale di 1. Esempio 2: M=I**A**J con I=2, J=4 interi e A=0.5 reale. 1) calcolo 2**0.51.414213 (reale per la regola 3); 2) calcolo 1.414213**43.999994 (ancora reale);

3) M assume il valore finale 3, anche se "normalmente" doveva venire 4. Da notare in questo esempio che se la prima operazione fosse stata A**J il risultato finale sarebbe stato 1. Esercizi (sia X=1., Y=6., Z=3.). Calcolare: 1 I=45/4*4 2 A=4-6+18.0/3/3 3 I=(X+Y/Z)**2 4 I=((X+Y)/Z)**2 5 I=(X+Y)/Z**2 6 I=X+(Y/Z)**2 soluzione
44 0.0 8 o 9 5 0 4 o 5

Parte B. I principali comandi del FORTRAN.


[HOME] 7 Un esempio di programma Le istruzioni nel Fortran devono essere scritte con un formato preciso, come pu essere visto nell? esempio seguente, dove, per comodit, riportata anche la numerazione delle righe e delle colonne: Esempio 7.1 colonne:
1 2 3 4 1234567890123456789012345678901234567890.....

C 10

PROGRAM PROVA programma per calcolare il peso di un oggetto REAL MASSA DATA GRAV/9.8/ WRITE(6,*) ' DAI LA MASSA IN KILOGRAMMI ' READ(5,*) MASSA PESO=MASSA*GRAV WRITE(6,*) ' IL PESO VIENE= ',PESO,' NEWTON ' WRITE(6,*) ' 1 PER CONTINUARE '

READ(5,*) IC IF(IC.EQ.1) GOTO 10 STOP END

La lunghezza di ogni riga (o "record") pu essere al massimo di 80 caratteri (o colonne), ma vietato scrivere nelle ultime 8 posizioni (colonne 73-80) in quanto venivano usate per numerare le schede. Inoltre, le prime sei colonne servono per uso speciale e quindi le istruzioni FORTRAN devono sempre partire dalla colonna 7. Alcuni degli usi speciali sono mostrati nel programma di prova: se nella prima colonna compare il segno C o * (asterisco) allora l'intera linea considerata come di "commento" ed ignorata dal computer; un numero che compare nelle colonne 1-5 serve per "etichettare" la particolare riga e si utilizza come riferimento per comandi successivi (cos l'etichetta 10 nella riga 5 usata dal comando GOTO della riga 11). Queste etichette posso stare nell'intervallo da 1 a 99999. Importante: non usare la colonna 6! Infatti, se la colonna 6 di una linea contiene un qualsiasi carattere (lettera o numero), allora i comandi di quella linea sono considerati come la continuazione dei comandi della riga precedente; si possono aggiungere fino a 19 continuazioni seguenti una prima linea. Da notare infine che non importante se i comandi sono scritti in maiuscolo o minuscolo. Esaminiamo ora brevemente il programma dell'esempio 7.1. La prima riga contiene il nome del programma definito con il comando PROGRAM (questa istruzione si pu anche omettere), poi c' una riga di commento per spiegare a cosa serve il programma. Quindi, con l'istruzione REAL si definisce reale la variabile MASSA, poi si assegna il valore di g (accelerazione della gravit) memorizzandolo nella variabile GRAV. Il programma a questo punto si arresta e aspetta di leggere (READ) al terminale la massa dell'oggetto che viene poi memorizzata nella variabile MASSA; si calcola PESO=MASSA*GRAV; infine si scrive il valore della variabile PESO. Ora il programma chiede se continuare il calcolo per altri oggetti: se si assegna alla variabile IC il valore 1 il programma ritorna (GOTO) alla lettura del nuovo valore di MASSA; altrimenti l'esecuzione finisce (STOP). In questo programma si trova un primo esempio di una costante di tipo "carattere" o stringa: la sequenza di caratteri racchiusa da due apostrofi consecutivi nell'istruzione WRITE; il computer tratta le stringhe semplicemente come un insieme di caratteri e non come variabili numeriche. Quindi, l'istruzione della riga 8 produrr sullo schermo del terminale una riga del tipo
IL PESO VIENE = 0.9800000E+1 NEWTON

avendo assegnato alla variabile MASSA il valore 1. [HOME] 8 La definizione delle variabili

Come abbiamo visto nel paragrafo precedente, all' inizio di un programma FORTRAN, di solito, ci sono alcune istruzioni che servono per "personalizzare" il programma. Pi precisamente, se vogliamo usare una data variabile nel programma, all'inizio dobbiamo specificare: - il tipo della variabile (se lo vogliamo diverso da quello "standard"); - se a quella particolare variabile associato un solo valore numerico oppure un vettore o una matrice di numeri; - il valore che la variabile deve assumere all'inizio. Qui di seguito mostreremo questi punti uno a uno. 8.1 La dichiarazione di tipo Le prime istruzioniche devono apparire nel programma (subito dopo l'istruzione iniziale PROGRAM) riguardano la dichiarazione del tipo delle variabili che si vogliono usare nel seguito. Nel FORTRAN esiste la possibilt di fare una dichiarazione "esplicita" che associa ad ogni particolare variabile il suo tipo, come, per esempio,
REAL*8 VAR1,VAR2,VAR3 INTEGER*4 VAR4,VAR5 COMPLEX*8 VAR6

Con questa serie di istruzioni si specifica che le variabili VAR1,VAR2,VAR3siano di tipo R8 (reali a doppia precisione), VAR4,VAR5intere I4 e VAR6 una variabile complessa C8. Il numero che moltiplica le istruzioni REAL, INTEGER e COMPLEX corrisponde esattamente al numero di bytes che deve essere associato alla variabile; per esempio per definire variabili R4, R8 o R16, il numero che moltiplica l'istruzione REALdeve essere 4, 8 o 16, rispettivamente. Inoltre, nei casi "standard" REAL*4,INTEGER*4,COMPLEX*8si pu omettere il numero e scrivere semplicementeREAL,INTEGER,COMPLEX,rispettivamente. Da notare ancora che si pu usare il comando DOUBLE PRECISIONal posto del comando REAL*8, quindi le istruzioni
REAL*8 VAR1,VAR2

e
DOUBLE PRECISION VAR1,VAR2

sono completamente equivalenti. Un altro metodo per dichiarare il tipo delle variabili viene fatto con una dichiarazione "implicita", cio che associa il tipo della variabile alla lettera iniziale del suo nome; per esempio, per definire complesse C8 tutte le variabili che iniziano per C,D,E si scrive
IMPLICIT COMPLEX*8 (C,D,E)

o equivalentemente,
IMPLICIT COMPLEX*8 (C-E)

Una istruzione molto utile, per definire che tutte le variabili che iniziano con una lettera che non sia I,J,K,L,M,N (le lettere riservate agli interi) siano reali a doppia precisione
IMPLICIT REAL*8 (A-H,O-Z)

Ricordiamo che, all'inizio, il programma assume che le variabili che iniziano per I,J,K,L,M,N sono intere I4 e tutte le altre R4 (reali a singola precisione), e quindi, le istruzioni REAL,INTEGER,COMPLEXsono da usare solo se si vuole modificare questa convenzione iniziale. Nell' esempio 7.1, si usata l' istruzione REALper definire la variabile MASSA come reale a precisione singola, altrimenti MASSA sarebbe stata una variabile intera.

8.2 Vettori e Matrici Ad una variabile si pu associare non solo un singolo valore numerico ma tutta una serie di valori, per esempio un "vettore" o una "matrice" di numeri. Gli elementi di un vettore A in FORTRAN sono individuati dal nome della variabile-vettore A seguita da un numero intero (indice) racchiuso tra parentesi: A(1), A(2),.... Nello stesso modo, un elemento di una variabile-matrice B sono scritti in questa maniera B(1,1), B(1,2), . . . Naturalmente si possono definire matrici a tre e pi dimensioni, come C(1,1,1) ecc. Quando una variabile viene definita per la prima volta, il computer deve conoscere quanto spazio riservargli nella memoria. Se la variabile di tipo R4 e non un vettore od una matrice, lo spazio riservato sar di 4 bytes. Quando la variabile contiene un vettore o una matrice di numeri bisogna far conoscere al computer del numero degli elementi di cui sar composta, in modo che possa assegnare tutta una serie di bytes contigui. Per esempio, se A un vettore reale R4 di N elementi, lo spazio riservato ad A nella memoria dovr essere di 4N bytes. Questa dichiarazione di "dimensione" si pu fare usando le stesse istruzioni REAL,INTEGER,COMPLEX aggiungendo (tra parentesi) al nome della variabile il minimo ed il massimo valore che potr assumere l'indice, separate da un segno " :" (due punti); per esempio, le istruzioni
REAL*8 VAR1(0:10),VAR2(100) COMPLEX VAR3(10,0:2)

specificano che la variabile VAR1 sia un vettore composto da 11 numeri (in doppia precisione) il cui indice varia fra 0 e 10; VAR2invece sia un vettore composto da 100 numeri il cui indice varia fra 1 e 100 (se il limite inferiore omesso si assume che sia 1); infine VAR3 sia una matrice di 300 numeri complessi, con il primo indice che varia tra 1 e 10, mentre il secondo varia tra 0 e 2. C' un altro modo per dichiarare vettori/matrici, usando l'istruzione DIMENSION, che per specifica solo il numero di elementi associati a delle variabili ma non il loro tipo; quindi, per

definire gli stessi vettori come nell'esempio precedente si potrebbero usare le seguenti istruzioni
REAL*8 VAR1,VAR2 COMPLEX VAR3 DIMENSION VAR1(0:10),VAR2(100),VAR3(10,0:2)

8.3 La definizione dei valori iniziali Nella maggior parte dei computers il valore iniziale di tutte le variabili fissato essere zero; nei programmi FORTRAN possibile dare delle istruzioni in modo che, quando parte il programma, certe variabili siano inizializzate con valori dati. Questo effettuato tramite l'istruzione DATA, che prende la forma
DATAlista variabili/lista valori/,lista variabili/lista valori/,...

per esempio, per assegnare alla variabili reali A e B i valori iniziali di 1.0 e 2.0,e alla variabile intera I il valore 1, si possono usare equivalentemente una delle due istruzioni seguenti
DATA A,B,I/1.0,2.0,1/

o
DATA A/1.0/,B/2.0/,I/1/

Se a pi variabili si deve assegnare lo stesso valore iniziale, si pu usare questa scorciatoia:


DATA A,B,C/3*1.0/

che equivale a
DATA A,B,C/1.0,1.0,1.0/

Si pu usare l'istruzione DATA anche per inizializzare i valori di un vettore o di una matrice, come per esempio
DIMENSION A(3),B(10,10) DATA A/1.0,2.0,3.0/ DATA B/100*1.0/

Da notare che l'assegnazione del valore alla variabile nell'istruzione DATAavviene quando inizia l'esecuzione del programma e non dipende dalla particolare posizione in cui situata l'istruzione stessa (pu anche essere a met del programma). Naturalmente, l'istruzione DATA deve trovarsi dopo le istruzioni di definizione e dimensione delle variabili, cio il computer deve gi sapere di che tipo la variabile e se un vettore, una matrice, ecc. Una situazione che pu dare adito ad errori l'assegnazione di valori ad una matrice a due dimensioni. In questo caso basta ricordarsi che i valori devono essere scritti colonna per colonna. Per esempio, le istruzioni

DIMENSION B(2,2) DATA B/1.0,2.0,11.0,20.0/

portano ad avere B(1,1)=1.0 , B(2,1)=2.0 , B(1,2)=11.0,ecc. Con l'istruzione DATAsi intende assegnare particolari valori iniziali alle variabili, che nel corso del programma potranno assumere altri valori. Se si vuole dare ad una variabile un particolare valore (come per esempio assegnare alla variabile PIil valore di pi greco = 3.141 592 653 ...) che rimarr sempre lo stesso, si pu usare l'istruzione PARAMETERche prende la forma
PARAMETER(variabile=valore,variabile=valore,...)

Perci il modo migliore di dare il valore a PI


PARAMETER (PI=3.1415926536)

Con l'istruzione PARAMETERsi possono usare anche espressioni aritmetiche, per esempio
PARAMETER (T=1.0/3.0,T49=4.*T/3.0)

da notare che l'assegnazione avviene con le regole usuali (e cos pure se ci sono operazioni tra numeri di tipo diverso, il computer seguir le regole mostrate nel paragrafo 6). Nell' esempio sopra mostrato si nota anche che possibile usare variabili nell'espressioni che compaiono nel PARAMETER, basta che siano gi definite attraverso un PARAMETERprecedente. L'istruzione PARAMETERdeve essere situata sempre dopo che il tipo della variabile sia stato definito. In un programma si possono inserire un qualsiasi numero di istruzioni DATAe PARAMETER. 8.4 Posizione delle istruzioni sopra elencate Ricapitolando, il tipico ordine con cui appaiono queste istruzioni di inizializzazione e definizione di variabili il seguente:
PROGRAM .... REAL , INTEGER , COMPLEX ... DIMENSION ... DATA , PARAMETER ....

[HOME] 9 Le istruzioni di scrittura e lettura Durante l'esecuzione di un programma importante "comunicare" con il computer; come si

visto nell'esempio 7.1, all'inizio del programma ci saranno alcune istruzioni di lettura (READ) per assegnare i valori iniziali di alcune variabili, e alla fine sar necessario fare scrivere (WRITEe PRINT) dal computer i risultati. Per esempio, per eseguire l'istruzione WRITEil computer ha bisogno di conoscere i) dove prendere i valori da scrivere (cio, il nome delle variabili che contengono i numeri che vogliamo conoscere) ii) dove scriverli (sul terminale, sul disco magnetico, ecc.) e, infine, iii) con che formato vogliamo che i dati siano scritti. Questo ultimo punto molto importante, in quanto se, per esempio, vogliamo scrivere una matrice di numeri ci piacerebbe scriverla sotto forma di tabella bidimensionale, ecc. Il FORTRAN non si occupa di queste cose, quindi si rende necessario usare una istruzione che si chiama FORMAT dove si pu specificare come vogliamo che appaiano i dati scritti. 9.1 Le istruzioni WRITE e PRINT La forma pi generale dell'istruzione WRITE la seguente
WRITE(UNIT=u,FMT=f,ERR=e) lista di variabili

Il numero intero u ha il compito di specificare dove vogliamo che il computer scriva i numeri (UNIT sta per unit di uscita = output); in pratica ci sono due posti dove far scrivere, sul terminale (UNIT=6) e sul disco magnetico; in questo ultimo caso i dati saranno posti nel file " fort.u", a meno che, con l'istruzione OPEN (si veda la sezione 9.4), non si definisca espressamente il nome di uno specifico file. Con FMT=f, dove " f" un numero intero, si istruisce il computer di scrivere i dati con il formato specificato dall?istruzione FORMATsituata nella riga la cui etichetta appunto il numero " f". Da notare che si pu omettere sia " UNIT=" che " FMT=", quindi si pu scrivere semplicemente WRITE(u,f,...), ricordando per che il numero che si riferisce all'unit di uscita deve precedere l'etichetta per il FORMAT. Se " f" uguale a un " *" (asterisco), allora il computer capisce che si vuole usare un formato "libero", cio quello predefinito nel FORTRAN (in questo caso, i valori delle variabili verranno stampati in una sola riga, con 7 decimali se sono variabili R4, 15 se sono R8, ecc.). Chiaramente in questo caso non necessaria l'istruzione FORMAT. La rimanente specifica (ERR=e) opzionale e serve per controllare che il processo di scrittura abbia avuto successo. Se questa specifica non presente e si verifica una condizione di errore (come, per esempio, quando si tenta di scrivere in un file e il disco pieno) il computer fermer l'esecuzione. Se invece si specificato ERR=e, dove " e" un altro numero di etichetta, quando si verifica una condizione di errore durante la scrittura il computer continuer l'esecuzione del programma dalla riga etichettata con "e". L'istruzione PRINT una versione semplificata di WRITE, ed il suo formato
PRINT f,lista di variabili .

dove " f" ha lo stesso significato descritto precedentemente di etichetta per l'istruzione FORMAT.

9.2 L'istruzione READ Il formato dell'istruzione READ simile a quello di WRITE, infatti si scrive
READ(UNIT=u,FMT=f,ERR=e,END=d)lista di variabili .'

Il significato di " u,f" lo stesso e anche qui si pu omettere di scrivere sia " UNIT=" che " FMT="; in questo caso la lettura avviene dal terminale se " u=5", e dal file " fort.u", se " u" un altro numero (6, comunque). Le specifiche ERR=eeEND=dsono opzionali; anche ora la specifica ERR=e ha la funzione di far continuare l'esecuzione dalla riga etichettata con " e" se avviene un errore in lettura. Nella istruzione READc' anche un' altra possibilit di errore, che capita quando, leggendo nel disco magnetico, si arriva alla fine del file di lettura; se si prova a leggere altri dati, il computer, non sapendo dove prenderli, sospender l'esecuzione. Se invece si specifica END=d il computer continuer l'esecuzione dalla riga etichettata con "d". 9.3 L'istruzione FORMAT Nelle istruzioni sopra descritte, la specifica del formato con cui i dati saranno presentati viene fatta con l?istruzione FMT=f, dove " f" era una etichetta di riga che si riferisce all'istruzione FORMAT. Questa si presenta nella forma seguente
f FORMAT(df1,df2,....,dfn)

dove " df1,df2,....,dfn" sono descrittori di formato. Nella seguente tabella ci sono i descrittori di formato usati per l?istruzione READ. Tabella 9.1 descrittori di formato per l?istruzione READ:
Iw Fw.d

leggi i successivi " w" caratteri come un intero leggi i successivi " w" caratteri come un reale R4 con " d"decimali (se il punto decimale non presente)

Ew.d stesso significato; Dw.d stesso significato ma per reali R8; nX

ignora i successivi " n"caratteri.

Vediamo alcuni esempi, in ognuno dei quali si leggeranno alcuni numeri dal file "fort.1", che supponiamo contenga le seguenti due righe:
123456789 123.1234 0.123456789

Il computer inizia a leggere dalla prima riga e dalla prima colonna (a sinistra) del file . Inoltre, come al solito, le variabili I,J sono intese essere intere, mentre le variabili A,Breali R4.

Esempio 9.1. Le istruzioni,


100 101 READ(UNIT=1,FMT=100) I,J FORMAT(I3,I4) READ(1,101) A,B FORMAT(F4.1,F4.2)

hanno come risultato di far assumere alla variabile Iil valore 123, alla variabile Jil valore 4567, ad Ail valore 0.12 ed a Bil valore 34.56 . Infatti, il FORMAT alla riga etichettata con 100, specifica che la prima variabile intera e va presa nei primi 3 caratteri; dopo avere letto variabile I, il punto di lettura del computer posizionato sulla quarta colonna della prima riga e quindi la seconda variabile letta nei successivi 4 caratteri. A questo punto il FORMAT 100 completato e il punto di lettura passer alla riga successiva (tutti i caratteri che rimangono nella prima riga saranno ignorati). Ora il computer legge il valore della variabile A usando il FORMAT 101; A deve essere di 4 caratteri quindi viene 0.12 (il punto considerato un carattere); inoltre c? il punto nel numero letto e quindi non si preoccupa di quanto vale il numero "d" (vedi tabella 9.1). Ora il punto di lettura il quinto carattere della riga due; il numero successivo deve essere di 4 caratteri, perci viene letto 3456; non avendo punto decimale diventa importante il valore di "d" che 2, quindi "B=34.56". Esempio 9.2 Le istruzioni,
100 READ(UNIT=1,FMT=100) I,J,A,B FORMAT(2I6,2F3.3)

danno come risultato:


I=123456 J=78912 A=3.1 B=0234

Nel leggere J stato trovato uno spazio vuoto che stato ignorato (789 12 78912); i successivi tre caratteri (3.1) sono stati assegnati ad A, e i tre successivi (234) a B; qui non c' la virgola e quindi B=0.234 . Da notare che 2I6 equivale a I6,I6. Cos nI6equivale in generale a I6,I6,I6,... ripetuto n volte; lo stesso vale per gli altri descrittori. Nel caso di lettura con formato libero, per esempio READ(1,*)I,J,A,B , la lettura avviene in maniera pi semplice, in quanto il computer considera i numeri come separati da spazi bianchi, senza contare il numero dei caratteri. Per esempio, per dare alle variabili I,J,A,Bil valore assegnato nell'esempio 9.2, si poteva semplicemente scrivere nel file "fort.1"
123456 78912 3.1 0.234

Ora vediamo i descrittori per l'istruzione WRITE.

Tabella 9.2 Descrittori di formato per l'istruzione WRITE:

Iw Fw.d Ew.d Dw.d nX

scrivi un intero nei successivi " w" caratteri scrivi un reale R4 nei successivi " w"caratteri con " d" decimali stesso significato di Fw.d ma con notazione esponenziale stesso significato di Ew.d ma per reali R8 scrivi i successivi " n" caratteri come "spazi bianchi"

'ab...z' scrivi la stringa di caratteri ab...z

Vediamo alcuni esempi: Esempio 9.3 Le istruzioni,


I=23 J=-12 A=3.14159 B=13.1 C=20.23 WRITE(6,100) I,J,A,B FORMAT(2I5,2F10.3,E10.3)

100

producono la seguente linea di uscita (sul terminale poich UNIT=6):


23-123.14213.100.202E+02

dove il simbolo " " stato usato per mostrare gli "spazi bianchi". Vediamo qui che i numeri interi sono stati scritti usando 5 caratteri (descrittore I5), mentre per i tre numeri reali sono stati usati 10 caratteri, con tre cifre decimali. Da notare che i numeri conosciuti con pi cifre decimali vengono arrotondati delle cifre in eccesso; se il numero di cifre decimali conosciuto minore, vengono aggiunti degli zero. L'ultimo numero stato scritto con notazione esponenziale, vale a dire mantissa + esponente. Nella scrittura necessario assicurarsi di avere abbastanza "spazio" per potere scrivere tutte le cifre dei numeri, se no il computer genera una sequenza di " *". Nell' esempio 9.3, se Ivalesse 100000 o -33333, 5 caratteri non sarebbero pi sufficienti; lo stesso se il numero reale Adiventasse (in valore assoluto) molto grande, per esempio A=3333333.14159. Con il descrittore " Fw.d"bisogna ricordarsi che si possono scrivere al massimo numeri con w-d-2 cifre prima del punto decimale (bisogna tenere conto della possibilit del segno negativo). Con il descrittore " Ew.d" non ci sono questi problemi, perch un numero molto grande viene sempre riportato ad avere mantissa tra 0 ed 1; per bisogna ricordarsi di mettere w>d+6, in quanto " w" deve contenere, oltre alla mantissa di " d" caratteri, un eventuale segno negativo, il punto decimale e 4 caratteri per l'esponente.

Nell' esempio 9.3 abbiamo visto che le variabili sono state scritte tutte sulla stessa riga (ricordiamo che nei normali terminali una riga non pu superare 80 caratteri). Si pu dire al computer di cambiare riga usando il descrittore " /". Per esempio, se il formato dell'istruzione di scrittura dell'esempio 9.3 fosse stato,
100 FORMAT(2I5/2F10.3,E10.3)

il risultato sarebbe stato il seguente


23-12 3.14213.100.202E+02

Dopo che i primi due numeri sono stati scritti su una riga, il descrittore " /" ha fatto scrivere le successive tre variabili nella riga seguente. Se un descrittore deve essere ripetuto "n" volte si puo scrivere " nFw.d", ecc., come nel caso della lettura. Inoltre, se si fanno scrivere un numero di variabili maggiore del numero di descrittori all'interno del FORMAT, essosar ripetuto da capo. Aggiungendo delle parentesi all'interno del FORMAT, si pu variare il numero di descrittori che saranno ripetuti. Esempio 9.4 Le istruzioni:
100 WRITE(6,100) A1,A2,A3,A4,A5,A6,A7,A8,A9,A0 FORMAT(4E10.3)

porta alla scrittura di 3 righe, di cui le prime due contengono quattro numeri e la terza due numeri in formato " E10.3". Se il formato fosse stato:
100 FORMAT(3E10.3,(E10.3))

si avrebbero quattro numeri nella prima riga e poi sei righe con un numero solo, poich il FORMAT verrebbe ripetuto solo a partire dal segno . Le parentesi possono essere usate anche nella seguente maniera:
100 FORMAT(E10.3,9(2X,F4.2))

Questo FORMATproduce una riga in cui il primo numero scritto con formato " E10.3", e i nove successivi con formato " F4.2" con due spazi bianchi fra ogni numero (lunghezza totale di riga scritta = 64 caratteri). 9.4 L'istruzione OPEN Uno degli aspetti pi importanti del calcolo elettronico risiede nella possibilit di salvare i dati su un mezzo magnetico (dentro un "file"), per poterli riutilizzare in un secondo momento, sia dallo stesso programma e sia da altri programmi. Abbiamo visto che con le istruzioni WRITE(u,...) e READ(u,...) possiamo eseguire delle letture e scritture su dei files che hanno un nome standard (sui computer UNIX sono i files di nome " fort.u"); in questo caso diremo che l'unit di numero " u" connessa al file di nome fort.u .Per

possibile ridefinire il file connesso ad una data unit tramite l'istruzione OPEN; in questo modo si possono evitare interferenze tra programmi diversi, interferenze che possono nascere quando entrambi i programmi per esempio scrivono sulla stessa unit. L'istruzione OPEN prende la forma,
OPEN(UNIT=u,FILE='fn',STATUS='st',FORM='fm')

dove " fn" il nome del file che deve essere connesso all'unit " u". Dopo che il computer ha trovato questa istruzione nel programma, le eventuali operazioni di scrittura e lettura associate all'unit " u" sono effettuate sul file " fn" e non pi sul file fort.u. La specifica STATUS pu essere OLD, NEW, UNKNOWN, SCRATCH e serve per informare il computer se il file gi esiste o no. Se " st" OLDsignifica che il file deve gi esistere (questa informazione utile quando il computer deve leggere dati da quel file), mentre se NEWsignifica che il file non deve gi esistere (utile quando si deve scrivere dati su quel file); quando non siamo sicuri di come verr utilizzato il file (un po' per scrittura e un po' per lettura) possiamo usare lo status UNKNOWN. Se " st" SCRATCH allora il programma crea uno speciale file che verr cancellato quando il programma cesser l'esecuzione. La specifica FORM='FORMATTED' indica che il file conterr gli usuali caratteri (lettere, numeri, segni di punteggiatura, ecc.) in modo che il programmatore (o un altro tipo di computer) possa leggere il file; questa anche il modo standard di scrivere su un file. Eppure, il computer deve fare una certa quantit di lavoro per convertire i dati dalla rappresentazione interna binaria a quella "umana". Se i dati che vengono scritti nel file sono molti e servono solo per essere riletti dal computer non necessario convertirli nei caratteri usuali; il computer pu quindi scriverli nel file usando la propria rappresentazione; questo si pu fare usando la specifica FORM='UNFORMATTED'. Per leggere da un file " unformatted" si usano i comandi WRITE e READ senza la specifica di formato. Per esempio,
> OPEN(UNIT=1,FILE='myfile',FORM='UNFORMATTED', STATUS='SCRATCH') WRITE(1) A1,A2,A3,A4 ..... READ(1) A1,A2,A3,A4

Qualche volta utile disconnettere un file aperto con l'istruzione OPEN e per questo si usa l'istruzione CLOSE:
CLOSE(UNIT=u,STATUS='st')

Questa istruzione pu essere utile perch se il programma si interrompe in maniera anomala, ad esempio usando l'interruzione forzata " Ctrl-C", spesso i files aperti vengono perduti. Invece, l'istruzione CLOSE chiude la connessione tra programma e file che quindi sar scritto in maniera definitiva sul disco, evitando cos i pericoli da interruzione accidentale. Ci sono varie istruzioni che regolano la riga precisa da dove il computer inizier la scrittura o lettura. Quando si apre un file il punto di srittura la prima riga e dopo che sono state lette

o scritte n righe, il punto di posizionamento la riga n+1. L 'istruzione


REWIND u

causa il riposizionamento sulla prima riga, mentre


BACKSPACE u

porta il computer a riposizionarsi una riga indietro (quindi il computer pu per esempio rileggere la stessa riga una altra volta). Un altra istruzione importante
ENDFILE u

Questa istruzione scrive una riga speciale chiamata "ultima riga"; se si riposiziona la riga di lettura all'inizio con REWIND e poi si comincia a leggere di nuovo con READ(u,f,END='d'), arrivati alla "ultima riga" si verifica una condizione di errore che attiva la specifica END='d' dell'istruzione READ (se END='d' omesso il computer blocca l'esecuzione). Si pu quindi usare ENDFILE per avvertire che il file finito o per aggiungere righe alla fine di un file; per esempio, supponendo di avere scritto nell' unit=8 una "ultima riga", si possono usare le istruzioni seguenti:
C leggi il file fino alla "ultima riga" 20 READ(8,END=21) GOTO 20 21 BACKSPACE 8 C ora aggiungi nuova informazione WRITE(8) .... ..... C terminare con un ENDFILE per la prossima scrittura ENDFILE 8

9.5 L' istruzione NAMELIST Questa istruzione usata quando si devono leggere, per esempio dal terminale, i valori di molte variabili; in questo caso l' impiego dell'istruzione READ comporterebbe la battitura di una lunga serie di numeri alla tastiera; invece, con il READassociato all' istruzione NAMELIST possibile assegnare solo una parte di dati, mentre l' altra parte mantiene i valori inalterati (magari assegnati con istruzioni DATA). In pratica, l' istruzione NAMELIST definisce la lista di variabili che dovranno essere "lette":
NAMELIST /nn/ A,B,I,J,....

dove " nn" una sequenza di uno o pi caratteri definita dal programmatore, vale a dire un nome, che specifica la lista A,B,I,J,.., ecc.. Si possono avere pi liste specificate con istruzioni NAMELIST nello stesso programma (con nome diverso); queste istruzioni vanno poste dopo avere definito i tipi di variabile e dimensionato i vettori. Quindi, per leggere i valori alle variabili definite nel NAMELIST di nome " nn" si scrive:
READ(5,nn)

Quando il computer si arresta e aspetta di leggere i dati, bisogna usare il seguente formato (il simbolo " " raffigura uno "spazio bianco"),
&nnA=1.,I=2,B=0./

Come si vede dal precedente esempio, si possono assegnare i valori in un ordine arbitrario e non necessario assegnare valori a tutte le variabili. Come si detto precedentemente, in questo caso, le variabili non specificate conservano il valore che avevano prima dell'istruzione READ(5,nn). [HOME] 10 L'istruzione DO L'istruzione DO serve per ripetere una parte di programma un certo numero di volte, creando un cosiddetto "loop" (ciclo). Un loop pu contenere qualsiasi altra istruzione FORTRAN, anche un altro loop; in questo caso si parla di loops "annidati" (nested). L'istruzione DO prende la forma,
DO ll VAR=V1,V2,V3

dove " ll" una etichetta di riga che identifica l'ultima riga di istruzioni compresa nel gruppo di righe da ripetere; " VAR" il nome di una variabile (usualmente una variabile intera), mentre " V1,V2,V3" rappresentano rispettivamente il valore iniziale, il valore finale e di quanto " VAR" deve aumentare ogni volta che il loop ripetuto; VAR,V1,V2,V3 devono essere variabili o costanti numeriche dello stesso tipo. Inoltre, se " V3" ha valore 1, si pu anche omettere. Il loop viene ripetuto un numero Nrip di volte pari a
Nrip =MAX(0,INT[(V2-V1+V3)/V3])

Da notare che l'ultimo valore che assumer la variabile " VAR"


VARmax= V1+V3*Nrip

che pu non coincidere necessariamente con V2 (comunque risulta sempre VARmax V2). Per esempio il comando DO 10 I=1,10,2genera un loop ripetuto (10-1+2)/2=5 volte, quindi la variabile I assumer in sequenza i valori 1,3,5,7,9. Il comando DO 10 I=10,9,2 invece porta a Nrip=0, ed in questo caso, l'intero gruppo di istruzioni contenuto nel loop sar completamente ignorato. Il computer segue le seguenti regole quando deve eseguire un loop: 1 calcola Nrip 2 pone VAR=V1

3 se Nrip=0 esce dal loop (salta al punto 7) 4 esegue le istruzioni comprese tra la riga con il DO e la riga successiva a quella con etichetta ll

5 somma V3 a VAR 6 sottrae 1 da Nrip e salta al punto 3 7 passa all'esecuzione dei comandi che risiedono nelle righe successive alla riga etichettata con ll

Si pu discutere sul valore che assume la variabile VAR all'uscita del loop. Se il loop completato normalmente, dalle regole precedenti segue che VAR ha il valore VARmax+V3. Invece, se nelle righe contenute nel loop c' una istruzione di salto (GOTO) che porta al punto 7 prima che il loop sia terminato (vale a dire prima che Nripraggiunga il valore zero), il valore di VAR all'uscita del loop l'ultimo assegnato al punto 5, e quindi dipender da caso a caso. Come ultima riga del loop, spesso si usa l' istruzione
ll CONTINUE

(dove ll l'etichetta di riga definita nel comando DO) che non esegue nessuna operazione. Come abbiamo detto, si possono avere loops annidati; in questo caso bisogna considerare che il loop pi interno dovr essere stato completato quando si arriva all'ultima istruzione del loop esterno. Vediamo alcuni esempi nella tabella 10.1.

Tabella 10.1 Annidamenti validi e non validi.

giusto
DO 1 I=1,10 DO 2 J=1,10 ....... 2 CONTINUE 1 CONTINUE

giusto
DO 1 I=1,10 DO 1 J=1,10 ...... 1 CONTINUE

errato
DO 1 I=1,10 DO 2 J=1,10 ...... 1 CONTINUE 2 CONTINUE

Nel terzo caso, l'etichetta del loop pi esterno si trova prima dell'etichetta che specifica la

fine del loop pi interno e quindi questa serie di istruzioni non valida. Nell'istruzione DO si pu anche omettere il numero di etichetta; in questo caso, per specificare il gruppo di istruzioni che saranno ripetute bisogna inserire una riga con il comando END DO (cio, il loop comprender le istruzioni comprese tra la riga con DO e quella con END DO). Per concludere la discussione dell'istruzione DO, si deve avvertire che non permesso, nelle istruzioni dentro un loop, cercare di modificare il valore delle variabili VAR, V1, V2 eV3. [HOME] 11 Decisioni Insieme alle espressioni aritmetiche, il FORTRAN contiene espressioni logiche o criteri, che possono assumere il valore di vero e falso. Le espressioni logiche possono essere usate con l'istruzione IF per dare al programma la possibilit di prendere delle decisioni e quindi eseguire differenti parti di programma a seconda del risultato di quelle decisioni. Il formato dell'istruzione IF il seguente,
IF(criterio 1) THEN gruppo di istruzioni 1 ELSE IF(criterio 2) THEN gruppo di istruzioni 2 ...... ELSE IF(criterio N) THEN gruppo di istruzioni N ELSE gruppo di istruzioni N+1 END IF

Il significato dei comandi IF ("se"), THEN ("allora") e ELSE ("altrimenti") identico a quello delle corrispondenti parole inglesi. Nell? esempio precedente si ha: se il criterio 1 risulta "vero" allora si esegue il gruppo di istruzioni 1; se il criterio 1 "falso" ma il criterio 2 "vero", allora si esegue il gruppo di istruzioni 2; se i criteri 1,. . .,I-1 sono "falsi" e il criterio I "vero" allora si esegue il gruppo di istruzioni I, ecc. Infine, se tutti i criteri sono "falsi" allora si esegue il gruppo di istruzioni N+1. In tutti i casi, dopo avere eseguito un singolo gruppo di istruzioni, il controllo passa alle istruzioni seguenti la riga con il comando END IF. Si possono anche avere istruzioni pi semplici come

IF(criterio) THEN gruppo di istruzioni a ELSE gruppo di istruzioni b END IF o IF(criterio) THEN gruppo di istruzioni END IF o IF(criterio) istruzione Quando non si specifica ELSE come negli ultimi due esempi, e il criterio risulta "falso", il computer passa direttamente all?esecuzione delle istruzioni successive. Esaminiamo ora la forma dei criteri pi semplici, detti anche "espressioni logiche elementari", che sono elencate nella tabella 11.1.

________________________________________________________________ Tabella 11.1 Le espressioni logiche elementari (A e B sono due variabili). A.EQ.B vero se A=B e falso se AB. A.NE.B vero se AB e falso se AB. A.GT.B vero se A>B e falso se AB. A.GE.B vero se AB e falso se A<B. A.LT.B vero se A<B e falso se AB. A.EQ.B vero se AB e falso se A>B. ________________________________________________________________

Da notare che nei criteri si possono usare anche espressioni aritmetiche complesse al posto delle variabili A e B , come nell? esempio seguente: IF(A+10./D1 .EQ. B**2.) THEN .... In questi bisogna tenere conto che prima vengono eseguite tutte le operazioni numeriche e successivamente viene valutata l?espressione logica. possibile combinare le espressioni logiche elementari presentate nella tabella 11.1 in criteri pi complessi, usando gli operatori .AND., .OR. e .NOT. . Questi operatori non agiscono tra espressioni numeriche ma tra espressioni logiche come specificato nella tabella 11.2. ________________________________________________________________ Tabella 11.2 Gli operatori logici .AND.,.OR. e .NOT. (c1,c2 sono criteri, quindi hanno il valore di vero o falso). c1.AND.c2 vero se c1 e c2 sono ambedue veri, mentre falso se almeno uno falso. c1.OR.c2 vero se dei criteri c1,c2 almeno uno vero, mentre falso se ambedue sono falsi. .NOT.c1 vero se c1 falso, mentre falso se c1 vero (riversa il valore di c1). ________________________________________________________________ Esempio 11.1. Sia I=1, J=1 e K=2; criterio:risultato: I.EQ.J.AND.I.EQ.K falso I.EQ.J.OR.I.EQ.K vero I.EQ.J.AND..NOT.I.EQ.K vero Un singolo criterio pu contenere un numero arbitrario di espressioni logiche semplici, tutte unite con gli operatori .AND., .OR. e .NOT. . In questo caso, necessario conoscere la priorit delle varie operazioni, come specificato nella tabella 11.3. ________________________________________________________________ Tabella 11.3 La priorit delle varie operazioni nella valutazione di un criterio. PrioritOperazione

alta espressione numerica . . . espressione logica semplice . . . .AND. . . . .OR. bassa .NOT. ________________________________________________________________ Quindi nella valutazione di un criterio, prima vengono eseguite tutte le espressione numeriche, poi le espressioni logiche semplici (quelle specificate nella tabella 11.1). Quindi si valutano gli operatori .AND., .OR., e .NOT., nell?ordine. possibile, inserendo coppie di parentesi tra espressioni logiche semplici, variare l?ordine delle operazioni; come al solito, le operazioni fra parentesi vengono eseguite prima. Esempio 11.2. Se c1, c2 e c3 sono tre criteri, avremo i seguenti casi (v sta per vero ed f per falso): c1 c2 c3 c1.AND.c2.OR.c3 c1.AND.(c2.OR.c3) vvvvv vvfvv vfvvv vffff fvvvf fvfff ffvvf fffff ____________________________________________________ Nel criterio c1.AND.c2.OR.c3 dell? esempio precedente si esegue prima l?operazione c1.AND.c2, e quindi l? .OR. , mentre nell?altro caso, l?ordine esattamente il contrario e, come si vede, il risultato pu essere diverso. In generale, volendo scrivere un criterio "complicato", opportuno costruirsi una tabella simile a quella precedente e considerare tutti i casi possibili. 11.1 L? IF aritmetico

E? possibile usare l?istruzione IF in un altro modo (IF "aritmetico"); questa procedura permette la scelta tra tre possibilita? a secondo del valore di una variabile. L? IF aritmetico prende la forma IF(X) l1,l2,l3 e causa la prosecuzione dell?esecuzione dalla riga di etichetta l1 se il valore della variabile X e? minore di zero, dalla riga etichettata l2 se X e? zero e dalla riga etichettata l3 se X e? maggiore di zero. Si pu usare anche una espressione numerica al posto della variabile dentro la parentesi: la scelta di dove continuare l?esecuzione e? allora causata dal valore negativo, zero o positivo dell?intera espressione. Da notare che questo uso di IF obsoleto e dovrebbe essere evitato perch comporta un notevole uso di "salti" e quindi una notevole complicazione del programma. 11.2 Espressioni logiche con numeri reali L?uso dei criteri con i numeri reali richiede una certa attenzione, come si pu capire dall? esempio seguente. Se A=2., B=3. e C=6. e il computer deve eseguire una istruzione del tipo IF(A*B.EQ.C) GOTO 100 il criterio dovrebbe essere "vero" e il computer dovrebbe saltare alla riga etichettata con il numero 100. Eppure, a causa degli errori di arrotondamento, la moltiplicazione potrebbe dare valore 6.0000001 o 5.9999999 o altro, (supponendo di lavorare con variabili in precisione singola) e il criterio risulterebbe falso. Questi errori non sono prevedibili (quindi non saremmo sicuri se il computer eseguirebbe l?istruzione GOTO 100) ed opportuno prendere alcuni accorgimenti. Per esempio, si pu scrivere al posto dell? IF precedente, la nuova istruzione IF(ABS(A*B-C).LT.1.E-5) GOTO 100 dove ABS(X) una funzione intrinseca, vale a dire un programma precostituito nel FORTRAN che d il valore assoluto del suo argomento X. Vedremo pi avanti altri esempi di funzioni intrinseche. Nell?esempio precedente, il criterio stato scritto tenendo conto della possibilit che A*B possa differire da C di una quantit pari a 0.000001 (in pi e in meno); in questo modo, poich l?errore di arrotondamento dovrebbe essere pi piccolo di questa quantit, siamo sicuri che il criterio non dipender pi da eventuali errori di arrotondamento. [HOME] 12 L'istruzione GOTO e i loop "condizionali" Abbiamo gi incontrato l?istruzione GOTO in istruzioni del tipo GOTO ll

dove ll una etichetta di riga posta da qualche parte nel programma (pu essere sia prima che dopo la riga con GOTO). Questa istruzione ha come conseguenza un "salto", vale a dire, l?esecuzione viene continuata dalla riga di etichetta ll e non con l?istruzione della riga successiva al GOTO. Questa istruzione un "GOTO incondizionato", poich il salto viene eseguito sempre e quindi va usato con molta cautela. Se il GOTO unito con un IF si parla di "GOTO condizionato"; questa istruzione usata frequentemente per formare loops senza ricorrere all?istruzione DO. In questo caso, se il salto viene eseguito ad una istruzione di una riga precedente, si corre il rischio di creare un loop infinito, cio un loop senza vie di uscita. Vediamo esplicitamente uno di questi casi illustrato nell? esempio seguente: l1 IF(criterio 1) GOTO l2 blocco di istruzioni A GOTO l1 l2 istruzioniB In questo caso, il blocco di istruzioni A ripetuto finche ` il criterio 1 rimane falso, mentre quando diventa vero si passa al blocco di istruzioni B. Risulta chiaro quindi che se per qualche motivo il criterio 1 rimanesse sempre falso, l?esecuzione rimarr perennemente bloccata dal GOTO l1. Un altro caso simile il seguente l1 blocco di istruzioni A IF(criterio 2) GOTO l1 istruzioni B La principale differenza fra i due casi mostrati che nel secondo caso il blocco di istruzioni A viene eseguito almeno una volta, contrariamente al primo esempio, dove se il criterio 1 fosse vero all?inizio, il blocco A verrebbe saltato completamente. Un altra istruzione che pu essere utile il cosiddetto "GOTO calcolato", che ha la seguente forma GOTO(l1,l2,...,ln),espressione numerica intera e causa un trasferimento di controllo alla riga etichettata l1 se l?espressione numerica intera valesse 1, alla riga etichettata l2 se l?espressione valesse 2, e cos via. Se l?espressione numerica negativa, zero o maggiore di n, il GOTO calcolato viene semplicemente saltato.

Parte C. La struttura dei programmi FORTRAN.


[HOME] 13 Il programma principale e i sottoprogrammi

Un programma FORTRAN completo comprende un programma "principale" (MAIN PROGRAM) e un numero variabile di sottoprogrammi (anche nessuni), che possono essere di due tipi: SUBROUTINE e FUNCTION. Per esempio, si supponga di avere un programma dove si esegue la stessa operazione, diciamo la derivazione, sopra diverse funzioni. In questo caso, conviene mettere la serie di istruzioni che calcola la derivata su una funzione generica dentro un sottoprogramma; a questo punto, se si devono derivare "n" funzioni, basta "chiamare", vale a dire eseguire, quel sottoprogramma "n" volte. La serie di istruzioni facenti parte di un sottoprogramma deve iniziare con una delle istruzione seguenti (intestazione): PROGRAM nome programma principale (facoltativa) FUNCTION nome(lista) sottoprogramma di tipo FUNCTION SUBROUTINE nome(lista) sottoprogramma di tipo SUBROUTINE dove "lista" rappresenta una lista di variabili dette gli "argomenti" dei sottoprogrammi. La fine di ogni unit di programma (programma principale o sottoprogramma) specificata dall' istruzione END. Per accedere alle istruzioni in un sottoprogramma di tipo function e, per esempio, di nome " AAA", basta usare questo nome come una qualsiasi variabile e inserirla in una espressione numerica (bisogna per aggiungere la lista degli argomenti); per chiamare una subroutine, per esempio di nome " BBB", invece si usa il comando CALL, come mostrato qui di seguito CALL BBB(lista) Un sottoprogramma pu chiamare altri sottoprogrammi e cos via; il computer ritorna ad eseguire le istruzioni del programma "chiamante" dopo che il sottoprogramma chiamato arriva all' istruzione RETURN. Esempio 13.1. Esaminiamo il programma seguente: PROGRAM main ..... A=FINT(X1,X2,X3) ...... CALL DERE(X4,X5,X6) ...... STOP END

FUNCTION FINT(Y1,Y2,Y3) blocco di istruzioni a FINT= ... RETURN END SUBROUTINE DERE(Y4,Y5,Y6) blocco di istruzioni b RETURN END Il "flusso" di istruzioni eseguite il seguente: l?esecuzione comincia dal programma principale, che in questo caso stato chiamato "main", e procede normalmente fino ad arrivare all? istruzione dove compare FINT(X1,X2,X3); il computer controlla se esiste una matrice tridimensionale di nome FINT e non trovandola cerca una function di quel nome (le variabili X1,X2,X3 sono gli argomenti di questa function); essendoci nel nostro caso un tale sottoprogramma, il computer trasferisce il controllo al gruppo di istruzioni "a" (che sono comprese tra l? istruzione FUNCTION FINT(Y1,Y2,Y3) e l?istruzione END) e comincer` ad eseguirle fino ad arrivare all? istruzione RETURN. A questo punto il controllo torna al programma principale, che riprende l? esecuzione da dove era rimasta, cio all? assegnazione della variabile A. L? esecuzione continua fino alla chiamata delle subroutine DERE; il controllo ora passa a questa subroutine che esegue il gruppo di istruzioni "b" fino ad arrivare all? istruzione RETURN, che fa ritornare di nuovo alle istruzioni del programma principale seguenti la riga con CALL DERE. L? esecuzione continuer fino al comando STOP. I sottoprogrammi e il programma principale formano delle unit ben separate; per esempio, non si pu con un comando GOTO saltare, partendo da un sottoprogramma, ad una istruzione di un sottoprogramma diverso. In particolare, ogni unit ha i suoi numeri di etichetta e in due o pi unit pu comparire la stessa etichetta. Anche le variabili usate da un sottoprogramma sono specifiche a quel sottoprogramma, vale a dire che il computer assegna diverse parti della memoria ad ogni unit di programma e da una unit non si pu accedere (a meno di usare il comando COMMON, si veda la sezione 14) alle variabili di un altra unit. In particolare, una variabile di una unit pu avere lo stesso nome di variabili definite in altre unit, senza pericolo di interferenze, in quanto come detto, ogni unit mette le variabili in una sua zona particolare di memoria. Una altra cosa da notare che le istruzioni che specificano il tipo delle variabili e/o il dimensionamento di vettori e matrici poste all? inizio di una unit riguardano solamente le variabili definite in quella particolare unit, e non hanno effetto sulle variabili definite in altre unit. Quindi il

programmatore deve avere cura di inserire all? inizio di ogni sottoprogramma tutte le opportune istruzioni descritte nella sezione 8. La via di comunicazione tra una unit A e un sottoprogramma B costituita dagli argomenti che compaiono, tra parentesi, accanto al nome della unit B. Come abbiamo visto dall? esempio 13.1 non importante che gli argomenti che compaiono nella chiamata del sottoprogramma nell? unit A abbiano lo stesso nome di quelli che compaiono nell? intestazione del sottoprogramma B. necessario tuttavia che siano dello stesso tipo (reale, intero, in doppia precisione, ecc.) e che contengono lo stesso numero di elementi, cio che abbiano la stessa dimensione (stesso numero di bytes). Se, nell? esempio 13.1, la variabile X1 del programma principale fosse un vettore di 100 elementi, anche Y1 (definito nella function FINT) dovrebbe essere un vettore di tale dimensione. Vediamo con un esempio come avviene questo passaggio di informazioni tra l?unit chiamante Ae per esempio una subroutine di nome BBB. In qualche punto dell? unit Asi trover una istruzione del tipo CALL BBB(X1,X2,X3) Supponiamo inoltre che l?intestazione della subroutine sia SUBROUTINE BBB(Y1,Y2,Y3) Quando il controllo passa dall? unit Aalla subroutine, alle variabili Y1,Y2,Y3, poste nella parte di memoria assegnata alla subroutine BBB viene associato il valore delle variabili X1,X2,X3, rispettivamente, valori che sono posti nella parte di memoria del programma chiamante A. Quando la subroutine restituisce il controllo all? unit A, avviene il processo inverso. Quindi se per esempio, nella subroutine BBB la variabile Y1 assumesse un nuovo valore, anche la variabile X1 del programma chiamante assumer quel valore, quando la subroutine restituisce il controllo. Inoltre, le variabili usate nella subroutine BBB, a parte naturalmente Y1,Y2,Y3, non sono accessibili dall? unit A; bisogna notare per che, se l? unit A richiamasse la stessa subroutine B altre volte, le variabili definite in B avrebbero conservato il valore che avevano al momento dell? ultimo ritorno all? unit chiamante A (in alcuni computer questo non automatico ma viene fatto se si usa l? istruzione SAVE). 13.1 External functions Esaminiamo ora alcune propriet dei sottoprogrammi di tipo FUNCTION; questi sottoprogrammi, scritti dal programmatore, si chiamano "esterni" (external) per distinguerli da quelli "interni" forniti direttamente dal FORTRAN (si veda la sezione 13.2). Come abbiamo gi detto la prima istruzione di una function deve essere (FNMAME un nome generico): FUNCTION FUNAME(VAR1,VAR2,...) dove VAR1,VAR2,... una lista di variabili che conterr i dati di entrata necessari per fare i calcoli. Con le function possiamo solo far calcolare un solo risultato che in uscita sar associato proprio al nome "FUMAME" della function. Quindi, dentro la function stessa si dovr trovare una istruzione del tipo (di solito giusto prima dell? istruzione RETURN):

FUNAME=espressione numerica Quindi FUNAME a tutti gli effetti una variabile, sia nel sottoprogramma che nel programma chiamante e dovr seguire tutte le regole che seguono le variabili, in particolare a riguardo del tipo. Se non si specifica niente, si assume che una function il cui nome incomincia con le lettere I, J, K, L, M, N sia intera e negli altri casi reale R4. Naturalmente, possibile definire il nome di una function come vogliamo usando i comandi REAL, COMPLEX, e INTEGER, come negli esempi seguenti REAL FUNCTION FUNAME(....) reale R4; REAL*4 FUNCTION FUNAME(....) reale R4; REAL*8 FUNCTION FUNAME(....) reale R8; DOUBLE PRECISION FUNCTION FUNAME(....) reale R8; INTEGER FUNCTION FUNAME(....) intera I4, ecc. Anche nel programma chiamante il nome della function usato come una variabile e pu entrare dentro espressioni numeriche, come per esempio: A=B*FUNAME(VAR1,VAR2,...)+ .... importante fare in modo che anche nel programma chiamante il nome della function sia dello stesso tipo di quello definito nella function stessa. Se per esempio, la function cominciasse con il comando DOUBLE PRECISION FUNCTION FUNAME, all? inizio del programma chiamante necessario definire FUNAME come variabile reale a doppia precisione tramite il comando REAL*8. 13.2 Intrinsic o internal functions Come abbiamo gi detto, esiste gi una serie di functions precostituite e che servono per il calcolo delle funzioni matematiche pi comuni, come le funzioni trigonometriche, ecc. Per ogni caso, ne esistono diverse versioni a seconda del tipo dell? argomento e della precisione con cui vogliamo conoscere il risultato. Per esempio, le funzioni adibite al calcolo del seno di un angolo X (in radianti) sono le seguenti SIN(X) X reale R4 risultato reale R4 DSIN(X) X reale R8 risultato reale R8 QSIN(X) X reale R16 risultato reale R16 CSIN(X) X complesso C8 risultato complesso C8 Come regola quasi generale si ha che la function che esegue il calcolo in doppia precisione si ottiene anteponendo al nome "normale" la lettera D, per la precisione quadrupla la lettera Q,

per avere il risultato con i complessi la lettera C, ecc. Una lista (parziale) di intrinsic functions, in precisione singola, usate per calcolare funzioni matematiche pu essere trovata nella tabella 13.1.

Tabella 13.1. Alcune intrinsic functions in precisione semplice usate per calcolare le funzioni matematiche pi comuni.
ACOS(X) ALOG(X)

arcocoseno di X logaritmo naturale di X

ALOG10(X) logaritmo in base 10 di X ASIN(X) ATAN(X) COS(X) COSH(X) ERF(X) EXP(X) GAMMA(X) SIN(X) SINH(X) SQRT(X) TAN(X) TANH(X)

arcoseno di X arcotangente di X coseno di X coseno iperbolico di X funzione errore calcolata in X esponenziale = eX funzione gamma calcolata in X seno di X seno iperbolico di X radice quadrata di X tangente di X tangente iperbolica di X

__________________________________________________________________

C? un? altra serie di functions che eseguono operazioni utili di vario tipo, come elencato nella tabella 13.2.

__________________________________________________________________

Tabella 13.2. Alcune intrinsic functions per operazioni varie. FunctionArgomenti Risultato Definizione AIMAG(X) complessorealeparte immaginaria di X; REAL(X) complessorealeparte reale di X; CONJG(X) complessocomplessocomplesso cognugato di X; FLOAT(X) interoreale R4trasformazione di X da I4 a R4; DFLOAT(X) interoreale R8trasformazione di X da I4 a R8; DBLE(X) reale R4 reale R8 trasformazione di X da R4 a R8; INT(X) reale R4 interotrasformazione di X da R4 a I4; IDINT(X) reale R8 interotrasformazione di X da R8 a I4; ABS(X) reale R4 reale R4 valore assoluto di X; DABS(X) reale R8 reale R8 valore assoluto di X; IABS(X) intero I4 intero I4 valore assoluto di X; MAX0(X1,.,XN) interi I4 intero I4 massimo tra X1,..,XN; AMAX1(X1,.,XN) reali R4 reale R4 massimo tra X1,..,XN; DMAX1(X1,.,XN) reali R8 reali R8 massimo tra X1,..,XN; MIN0(X1,.,XN) interi I4 intero I4 minimo tra X1,..,XN; AMIN1(X1,.,XN) reali R4 reale R4 minimo tra X1,..,XN; DMIN1(X1,.,XN) reali R8 reali R8 minimo tra X1,..,XN; __________________________________________________________________ 13.3 Statement functions Quando le istruzioni che compongono una function possono essere ridotte ad una sola, possibile definire quella function direttamente nel sottoprogramma che la deve usare. Questo modo di definire la funzione (chiamata "statement function", cio funzione dichiarata) deve essere piazzata senza alternative subito dopo le istruzioni che specificano il tipo e la dimensione delle variabili e subito prima di ogni istruzione di assegnazione. La forma dell? istruzione , per esempio, AAA(X1,.,XN)=espressione aritmetica

L? espressione aritmetica pu contenere: costanti; le variabili X1,.,XN; altre variabili definite nella stessa unit di programma; altre statement functions, basta che siano definite precedentemente; intrinsic functions; e altre funzioni esterne (basta che non modifichino il valore di X1,.,XN. L?uso di queste functions identico a quello descritto precedente: si possono inserire direttamente nelle espressioni aritmetiche che definiscono qualche variabile. Per esempio, la statement function AAA definita precedentemente pu comparire in una istruzione del tipo A=2.*(AAA(Y1,.,YN)+4.) Come gi discusso, al momento dell? esecuzione dell? istruzione A=..., il programma valuta l? espressione aritmetica associata alla statement function AAA, prendendo come valore delle variabili X1,.,XN i valori che sono associati alle variabili Y1,.,YN. I vantaggi maggiori di questo tipo di function stanno nella maggiore velocit di esecuzione; infatti, il computer non deve eseguire un trasferimento di controllo ad un altra unit di sottoprogramma, che richiede sempre un certo tempo, ma come se l? espressione aritmetica associato alla statement function fosse inserito direttamente nelle istruzioni dell? unit. In effetti, la statement function pu essere considerata semplicemente come un modo per semplificare la scrittura di identiche e ripetute espressioni numeriche. Da notare infine, che questo tipo di function strettamente locale, cio pu essere usata solamente nell? unit di programma dove dichiarata. 13.4 Subroutines Una subroutine la forma migliore per spezzare il programma in parti pi piccole, ognuna dedicata ad un compito specifico. Il programma chiamante accede alla subroutine tramite l? istruzione CALL: CALL SUNAME(ARG1,...,ARGN) che causa l? esecuzione del gruppo di istruzioni che iniziano con SUBROUTINE SUNAME(VAR1,...,VARN) e finiscono con l? istruzione END. Il controllo ritorna al programma chiamante quando la subroutine termina l? esecuzione con l? istruzione RETURN. Da notare che "SUNAME" semplicemente un nome usato per chiamare la subroutine e non una variabile. I risultati del calcolo sono passati al programma chiamante attraverso gli argomenti ARG1,...,ARGN della subroutine (un metodo alternativo quello di usare l? istruzione COMMON, come spiegato nella sezione successiva). [HOME] 14 Variabili globali Come detto nella sezione precedente, ogni sottoprogramma ha una parte di memoria riservata dove immagazzinare i valori associati alle proprie variabili (che sono dette

variabili locali). Nel FORTRAN prevista la possibilit di rendere alcune variabili accessibili a due o pi sottoprogrammi; queste variabili cos definite sono ora chiamate variabili globali. Per ottenere che alcune variabili diventino condivisibili tra le diverse unit del programma si usa l? istruzione COMMON, che ha il seguente formato COMMON /name/ VAR1,VAR2,.... dove VAR1,VAR2,... rappresenta la lista delle variabili che devono diventare globali. Per esempio, COMMON /EX1/ A,B,V(100),I,J definisce una lista di variabili, avente EX1 come nome di COMMON, comprendente le variabili A,B,I,J e il vettore V(100). Da notare che con questa istruzione si pu dimensionare direttamente eventuali vettori e/o matrici. Infatti nell? esempio precedente non necessario specificare le dimensioni di V in una istruzione DIMENSION. Alternativamente si pu scrivere COMMON /EX1/ A,B,V,I,J DIMENSION V(100) Poich, questa istruzione una istruzione che specifica una propriet delle variabili, va posta all? inizio del programma, prima delle istruzioni DATA e prima di ogni riga contenente espressioni numeriche. Se si inserisce in due o pi sottoprogrammi un dato COMMON, le variabili della lista saranno disponibili in tutte queste unit. Questo quindi un altro modo per passare dati tra il programma chiamante e il sottoprogramma e viceversa. Le variabili "nel COMMON" di un dato "nome" sono messe in un area di memoria a comune di quei sottoprogrammi dove compare l? istruzione COMMON/nome/. Da notare che il passaggio dei dati attraverso gli argomenti ad un sottoprogramma necessita un trasferimento di valori tra le aree di memoria delle due unit (chiamante e sottoprogramma); nel caso di trasferimento di una grossa quantit di dati questa procedura pu richiedere un certo tempo e quindi pu risultare pi conveniente mettere le variabili da trasferire in una area comune. Consideriamo uno stesso COMMON ripetutoin due (o piu?) unit differenti: i nomi delle variabili del COMMON che compaiono nelle varie unit possono essere diversi e anche il numero di variabili pu essere diverso; comunque importante che il numero dei bytes occupati dalle variabili sia lo stesso in tutti i casi; per fare un esempio, supponiamo che nell? unit A compaia COMMON /EX2/ A1,A2,B(10) ed in un'altra unit B COMMON /EX2/ Z(12)

Allora nell? unit B Z(1) assumer il valore di A1, Z(2) assumer il valore di A2, Z(3) assumer il valore di B(1), ecc. In questo modo si pu risparmiare sull? impiego di memoria, facendo occupare da pi sottoprogrammi solo una zona in memoria invece di molte sezioni separate, pur avendo la libert di usare variabili di nomi diversi per ogni unit di programma. 14.1 Inizializzare le variabili globali Le variabili globali (cio quelle inserite in un COMMON) non possono essere inizializzate con un comando DATA come spiegato nella sezione 8. Infatti, essendo una variabile globale "presente" in due o pi sottoprogrammi, si potrebbe per sbaglio assegnarle valori iniziali differenti da pi parti, creando cos una situazione conflittuale. Per evitare questi problemi, le variabili globali si possono inizializzare solamente in particolari sottoprogrammi chiamati BLOCK DATA. Questi sottoprogrammi contengono esclusivamente istruzioni di specifica di tipo e di dimensione delle varie variabili, istruzioni COMMON e istruzioni DATA. Non possono contenere invece istruzioni eseguibili, come espressioni numeriche, letture, scritture e richiami ad altri sottoprogrammi; inoltre, devono terminare con l? istruzione END, senza per contenere nessun comando STOP o RETURN. La forma generale la seguente: BLOCK DATA name specifiche di tipo e dimensione COMMON/CM1/ VAR1,VAR2,.... COMMON/CM2/ VAR3,VAR4,.... ..... DATA VAR1,VAR2,.../lista di valori/ DATA VAR3,VAR4,.../lista di valori/ ..... END In un programma si possono inserire un numero arbitrario di BLOCK DATA. [HOME]