Fortran
-
Upload
andrea-tallarico -
Category
Documents
-
view
135 -
download
12
description
Transcript of Fortran
~
l
"
I,Il
I
, l
, (i •
l.
GIANNI AGUZZIMARIA GRAZIA GASPARO
MARIA MACCONI
FORTRAN 77Uno strumento
per il calcolo scientifico
PITAGORA EDITRICE BOLOGNA
PARTE J - CONCETTI FONDAMENTALI
I. GLI ALGORITMI E LA LORO DESCRIZIONE
1.1. Introduzione............................................ 31.2. Il linguaggio dei diagrammi a blocchi. . . . . . 91.3. Il linguaggio delle funzioni ricorsive . . . . . . . . . . . . . . . . . . . . . . . . . 14
000355
AIiIUUI/Gup."oM.cc:onl
FORTRAMnPIi.gora Edit.
ISBN 88-371-0378-6
© Copyright 1987 Pitagore Editrice s.r.l., Via del Legatore 3, BolognaTutti i diritti riservati Riproduzione vietata.
Composizione e stampa: Tecnoprint. ViD del Legatore 3, BolognaCodice: 21/211
..
Indice
Prefazione . . . . . - - . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2. DAL LINGUAGGIO MACCHINA ALLA REALIZZAZIONE DEI LINGUAGGISIMBOLICI
2.1. Introduzione .2.2. Unità hardware di un elaboratore convenzionale .2.3. 11 linguaggio macchina .2.4. I linguaggi simbolici .2.5. La realizzazione di un linguaggio simbolico .2.6. Il sistema operativo - .
3. RAPPRESENTAZIONE DEI NUMERI
3.1. Numeri interi .3.2. Numeri reali. . . . . . . . . . . . . . . . . . . . . . . .3.3. Rappresentazione finita ed errori di arrotondamento .
PARTE JJ • IL FORTRAN 77
4. IL LINGUAGGIO FORTRAN
4.1. Introduzione .4.2. Alfabeto ···4.3. Costanti, nomi simbolici e parole chiave .4.4. Frasi eseguibili e non eseguibili. .4.5. Etichette - .4.6. Il formato delle linee .
5. COSTANTI E VARIABILI: ELEMENTI FONDAMENTALI DI OGNI ISTRUZIONE
5.1. Le costanti ed il loro tipo .
XI
212223252830
333739
474848494950
53
f
VI VII
6.
7.
5.2. Le variabili ed il loro tipo .5.3. L'istruzione IMPUCIT .
LE ESPRESSIONI
6.1. Espressioni aritmetiche .6.2. Espressioni reiazionali .6.3. Espressioni logiche .6.4. Espressioni costanti .
Esercizi .
LA FRASE DI ASSEGNAZIONE
7.1. Introduzione ·7.2. Assegnazione aritmetica .7.3. Assegnazione logica .
Esercizi .
5658
61767779
80
838386
87
11. LE VARIABILI DIMENSIONATE
Il.1. Introduzione .Il.2. Nomi di variabili dimensionate e istruzione DlMENSION .Il.3. Nomi di elementi di variabile dimensionata .IlA. Disposizione in memoria degli elementi di una variabile dimensionata .11.5. Esempi di utilizzazione delle variabili dimensionate .
Esercizi .
12. ELABORAZIONE DELLE INFORMAZIONI DI TIPO CARATTERE
12.1. Memorizzazione dei caratteri .12.2. Le costanti e le variabili di tipo carattere .12.3. Sottostringhe ed espressioni carattere .12A. Assegnazione fra stringhe di caratteri. .12.5. Lettura e scrittura dei dati di tipo carattere .12.6. Confronto tra espressioni carattere .12.7. Funzioni intrinseche perla manipolazione dei caratteri .
Esercizi .
151153156160164
171
173174178180183185187
1918. ALCUNI SEMPLICI PROGRAMMI
8.1. Introduzione .8.2. Frasi di ingresso/uscita guidate dalla lista .8.3. Le istruzioni PROGRAM, STOP e END .8A. L'istruzione PARAMETER .8.5. Altri esempi .
Esercizi .
9. SCELTE E DECISIONI
9.1. Controllo esplicito dell'esecuzione: !'istruzione GOTO-incondizionato .9.2. Costrutto IF ·THEN·ELSE .9.3. Strutture decisionali annidate .9 A. Strutture decisionali concatenate .9.5. Riepilogo .9.6. If-logico: una struttura particolarmente semplice .9.7. GOTO-calcolato .9.8. IF-aritmetico .
Esercizi .
lO. CICLI
10.1. Strutture di ripetizione .10.2. Istruzione DO .10.3. Il cìclo-Do .10.4. Cicli e strutture decisionali .10.5. Trasferimento ad istruzioni fuori del rango .10.6. Cicli-Dì) annidati. .
Esercizi .
8989929597
98
101102105111114116120121
121
125132133140143145
148
13. OPERAZIONI DIINGRESSO/USCITA CON FORMATO
13.1. Alcune considerazioni sulle frasi di ingresso/uscita guidate dalla lista .13.2. Specificazioni di formato .13.3. Rappresentazione dei dati numerici sui records di l/O .BA. Il descrittore Iw per dati di tipo intero .13.5. I descrittori Fw.d, Ew.d, DW.d per dati di tipo reale e doppia precisione .13.6. I descrittori ripetibili per dati di tipo complesso .13.7. I descrittori ripetibili per dati di tipo carattere .13.8. Istruzioni di ingresso/uscita con formato relative ai mezzi standard .13.9. Interazione fra lista di ingresso/uscita e specificazione di formato .13.10. Controllo della spaziatura verticale su stampante .13.11. I principali descrittori non ripetibili .13.12. La lista di ingresso/uscita .13.13. Le frasi READ (u, f) e WRITE (u, f) .13.14. Esempi di stampa di variabili dimensionate .13.15. Altri descrittori .
Esercizi....................................................
]4. DEFINIZIONE E UTILIZZAZIONE DEI SOTTOPROGRAMMI
14.1. Programma principale e sottoprogrammi .14.2. La prima istruzione di un sottoprogramma .14.3. Il corpo di un sottoprogramrna e l'istruzione RETURN .14.4. I sottoprograrnmì SUBROUTINE e la frase CALL .14.5. I sottoprogrammi FUNCTION .14.6. Le funzioni definite da una frase .14.7. Le funzioni intrinseche .
Esercizi .
193194197198199202203205208214215219222223
228
234
239243244245252259261
271
VIIIIX
381384389392
395397
Differenze con il subset 1anguage .Prìncipali differenze fra il FORTRAN 77 e il FORTRAN 66 .Ordinamento delle istruzioni F77 .La codifica dei caratteri in ASCII e EBCDlè' ........................
APPENDICI
Al.A2.A3.A4.
Bibliograflll .Indiceanalitim ............................ ...................... .
15. ARGOMENTI MUTI ED ARGOMENTI ATTUALI
15.1. Associazione tra argomenti muti ed argomenti attuali. 27515.2. Le variabili non dimensionate come argomenti muti " 27515.3. Le variabili dimensionate come argomenti muti. " 27715.4. Dimensionamento variabile e dimensionamento indefinito " 28015.5. Argomenti muti di tipo carattere. . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 28915.6. l nomi di sottoprogrammi come argomenti muti. Le frasi EXTERNAL e
INTRINSIC " 29215.7. Asterischi come argomenti muti. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 299
Esercizi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 301
16. USO FLESSmlLE DELLA MEMORIA
16.1. L'istruzione COMMON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 30716.2. Utilizzazione dei blocchi COMMON " 30916.3. L'istruzione EQUlVAlENCE " 31616.4. Interazione fra istruzioni COMMON ed EQUIVALENCE " 31916.5. La frase DATA 32116.6. Sottoprogrammi BLOCK DATA " 325
Esercizi " 327
17. USO FLESSmlLEDEI SOTTOPROGRAMMI
17.1. Punti di ingresso secondari: l'istruzione ENTRY " 33117.2. Punti di ingresso secondari di un sottoprogramma SUBROUTINE " 33417.3. Punti di ingresso secondari di un sottoprogramma FUNCnON " 33717.4. Le variabili interne di un sottoprogramma e l'istruzione SAVE " 34117.5. I blocchi COMMON etichettati e l'istruzione SAVE " 347
Esercizi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 349
18. TRATTAMENTO DEI FILES
18.1. Introduzione..................................... 35118.2. Records e files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 35118.3. La forma generale delle frasi di I{O . . . . . . . . . . . . . . . . . . . . . . . 35518.4. Connessione di un file esterno: frasi OPEN e CLOSE . . . . . . . . . . . . . . 35918.5. Frasi di posizionamento: BACKSPACE e REWIND . . . . . . . . . . . . . . 36518.6. Files ad accesso diretto. . . . . . . . . . . . . . . . . . . . . . . . . . . 36818.7. Indagine sulle unità dillO e sui files: frase INQUIRE . . . . . . . . . . . . . . 37118.8. Files interni. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Esercizi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
I\ \ ~
Prefazione
In questo volume è descritta l'ultima versione del linguaggio FORTRAN nota
come FORTRAN 77 e definita nel documento X3.9.1978 dell'A m erican National
Standard Institute. Questa versione, ormai disponibile nella maggior parte degli
elaboratori elettronici, costituisce un importante strumento per la realizzazione
di programmi direttamente utilizzabili su sistemi di calcolo anche molto diversi
tra loro.
E' noto che le principali applicazioni del linguaggio FORTRAN sono di tipo
numerico ed è per questo motivo che il testo è rivolto principalmente a chiun
que abbia interesse ad utilizzare un elaboratore per risolvere problemi di natura
scientifica o tecnica. Va però osservato che il FORTRAN 77 allarga le possibi
lità di applicazioni anche a problemi di carattere gestionale in quanto permette
sia la manipolazione dei caratteri che l'utilizzazione di [iles di dati ad accessodiretto. In ogni caso, una corretta utilizzazione del FORTRAN non può prescinde
re dalla conoscenza di alcuni prerequisiti che, secondo gli autori, devono far parte
del bagaglio culturale di chiunque utilizzi Wl elaboratore elettronico. Per questo
il testo è diviso in due parti. La prima parte può non interessare il lettore già
esperto nell'uso dei linguaggi di programmazione ed è costituita da tre capitoli
nei quali si danno le nozioni di base su alcuni argomenti fondamentali quali gli
algoritmi e la loro descrizione (capitolo 1), la struttura degli elaboratori elet
tronici e la realizzazione dei linguaggi simbolici (capitolo 2), le modalità di rap
presentazione dei numeri e gli errori di arrotondamento (capitolo 3J.La descrizione del FORTRAN, oggetto della seconda parte del libro, è orga
nizzata in modo da fornire il più rapidamente possibile gli strumenti necessari per
poter scrivere alcuni semplici programmi. Per questo, dopo aver descritto nei
capitoli 4, 5 e 6 gli elementi di base del linguaggio, le modalità di definizione
delle variabili e delle costanti e le caratteristiche della formalizzazione e valuta
zione delle espressioni, nei capitoli 7 e 8 vengono presentate le istruzioni che
consentono di scrivere alcuni programmi completi comprendenti frasi di asse
gnazione, di lettura dei dati e scrittura dei risultati.
...
XII
Nei due capitoli successivi vengono analizzati i costrutti che permettono di
realizzare in FORTRAN gli schemi teorici che stanno alla base della programmazione strutturata: nel capitolo 9 viene presentato il costrutto decisionale IF
THEN-ELSE e nel capitolo lO quello di ripetizione controllato dalla istruzione DO.
Nel capitolo Il sono descritte le modalità di utilizzazione delle variabili dimensionate mediante le quali è possibile tradurre in FORTRAN la notazione vet
toriate comunemente usata nei problemi di natura scientifica, mentre il capitolo
12 è dedicato alla descrizione delle possibilità offerte dal FORTRAN 77 per la
manipolazione di stringhe di caratteri.
Nel capitolo 13 vengono presentate le operazioni di ingresso/uscita con forma
to. Questo argomento, estremamente vario in quanto il FOR TRAN 77 offre al
riguardo moltissime possibilità. viene affrontato cercando di fornire prima le
nozioni elementari e poi quelle più sofisricate in modo da distinguere le cono
scenze basilari da quelle necessarie solo per particolari operazioni di ingres
so/uscita.Nei capitoli 14, 15. 16 e 17 si trattano gli argomenti legati all'uso dei sottopro
grammi ovvero alla possibilità di decomporre un programma in più unità ciascuna
delle quali può essere scritta e compilata in modo autonomo. Il testo si chiudecon il capitolo 18 nel quale vengono descritti il trattamento e la gestione deifiles di dati.
Nel testo l'iene rigorosamente descritta la sintassi delle istruzioni FORTRAN,·il significato e l'uso di ogni istruzione è inoltre spiegato tramite numerosi e
sempi. Sono anche sottolineate le differenze rispetto al FORTRAN 66 in modo
da rendere il libro utile a chi abbia a disposizione un sistema di calcolo che realizza una versione del FORTRAN precedente al FORTRAN 77. Ogni capitolo è
accompagnato da esercizi che permettono al lettore di verificare immediata
mente il lil'ella di apprendimento raggiunto.La stesura dei capitoli 2, 8, 16, 18 è stata curata dal primo autore che si è
anche occupato del trattamento della ricorsivuà (§ 1.3) e delle funzioni intrin
seche (§ 14.5). Il pro! Aguzzi si è anche assunto il compito di verificare la
correttezza di tutti i programmi presentati nel testo, utilizzando a tale scopo un
elaboratore IBM PC AT con compilatore PROFORT 77 e un elaboratore VAX
11/730 con compilatore VAX-ll FORTRAN V 3.0. Il secondo autore ha curato
la stesura dei capitoli 1,4,11,13,14,15,17, mentre il terzo autore ha curato
quella dei rimanenti capitoli.L'impostazione usata in questo testo è stata seguita per insegnare il linguaggio
FORTRAN agli studenti dei corsi di Calcolo numerico tenuti a Firenze nel Corsodi laurea in Matematica e nella Facoltà di Ingegneria, coinvolgendo, oltre agli
autori, i pro! F. Fontanella, A. Pasquali, P. Costantini e la d.ssa R. Morandi.ai quali vanno i più sinceri ringraziamenti per i numerosi e utilissimi consiglie suggerimenti.
IConcetti fondamentali
Il,
1Gli algoritmie la loro descrizione
1.1. Introduzione
Con il termine al~?!~tl1lfL~i intende una successione finita di istruzioni, assegnate in modo non ambiguo, tali che la loro esecuzione consenta di passare,
in un tempo finito, da una assegnata situazione iniziale (problema) ad una situa
zione finale (risultato). L'esecuzione delle istruzioni di un algoritmo presuppone
un insieme di dati che individuano, nella classe di problemi risolubili mediante
l'algoritmo, il problema da risolvere e la disponibilità~ di un esecutore capace
di effettuare, nell'ordine prestabilito, le azioni indicate dalle istruzioni. AI termine
dell'esecuzione si ottiene il rts!!!!!!~ che deve essere univocamente determinato
dall'insieme dei dati. Da quanto detto segue che un algoritmo non è altro che
la descrizione del calcolo di una funzione che associa, in modo univoco, il risul
tato all'insieme dei dati.
Nella stesura di un algoritmo devono essere tenute ben presenti le capacità
dell'esecutore per evitare istruzioni che non possono essere eseguite. In altri
termini, un algoritmo deve essere costituito da una successione di istruzioni
realizzabili mediante operazioni che l'esecutore sa eseguire (operazioni primitive).
L'ordine in cui devono essere eseguite queste operazioni, detto anche [lusso, è
di solito quello sequenziale a meno di esplicite indicazioni contenute nelle istru
zioni stesse. Gli esempi seguenti mostrano come sia possibile risolvere alcuni
problemi matematici supponendo di avere a disposizione un esecutore che possa
eseguire istruzioni formulate in lingua italiana ed in particolare sappia leggere,scrivere, eseguire le operazioni aritmetiche e confrontare tra loro due numeri.
La numerazione progressiva che precede la descrizione di ciascuna istruzione
definisce, visualizzandolo, il flusso sequenziale dell'algoritm o. Inoltre l'istru
zione «poni v = e» significa che, una volta determinato il valore di e, lo si indica
con il simbolo ~'. Ogni istruzione di questo tipo verrà chiamata nel seguito istruzione di assegnazione.
Esempio 1.1. Si vuoI determinare il più piccolo di una tema di valori.
4
Indicati con al' a2
e a3
i tre numeri assegnati, è possibile ottenere il risultato
r = min {al' a2, a
3} eseguendo quanto specificato nel seguente algoritmo:
Algoritmo 1.1.
1. Leggi: al' a2, a32. confronta al con a2· Se al > ~ allora: poni m = a2 ed esegui 3.
altrimenti: poni m = al ed esegui 3.
3. confronta m con a3 · Se m> a3 allora: poni m = a3 ed esegui 4.altrimenti: esegui 4.
4. poni r = m5. scrivi: r
6. stop.La prima istruzione impone l'acquisizione dei dati del problema. Supponendo
che essi siano i valori {3, 2, l} l'esecuzione delle successive istruzioni avviene nel
modo seguente:• si confronta 3 con 2 e, siccome 3> 2, si ha m = 2;• si confronta m con a3 ovvero 2 con 1 e, siccome 2 > 1, si ha m = 1;• il risultato r è posto uguale al valore di m ovvero, in questo caso, r = 1.
Se la tema di valori fosse stata {3, 2, 4} il confronto previsto dall'istruzione 3.
tra m = 2 ed a3
= 4 non avrebbe provocato nessuna modificazione di m ed il
risultato sarebbe stato r = 2.Il significato delle istruzioni 5. e 6. è intuitivo: la prima fornisce il risultato
r dell'algoritmo mentre la seconda impone la fine dell'esecuzione delle istruzioni.
Si osservi che l'algoritmo 1.1 è applicabile ad una qualunque tema di valori
in quanto è stato scritto indipendentemente dai dati effettivi del singolo pro
blema.
Esempio 1.2. Si vuol determinare il più piccolo tra n numeri reali.Indicati con a a
2a gli n valori assegnati, il risultato r = min {ak }l' , ..., n l .. k" n
pUÒ essere ottenuto con un algoritmo basato, come quello dell'esempio pre-
cedente su confronti successivi tra il valore m = min {~} ed ai con, l .. k" i - l
2 ~ i ~ n. Il numero di confronti necessari per determinare il risultato dipende
ovviamente da n in quanto, fissato il primo valore di m (m = al)' il risultato rè ottenuto dopo aver ripetuto n - l volte l'operazione di confronto. Le consi
derazioni fatte permettono di scrivere il seguente algoritmo che prevede tra i datidel problema oltre ai valori al' a2, ..., a
nanche il valore di n; esso è quindi appli
cabile ad una qualsiasi n-pla di valori, qualunque sia il numero n, n > l, di ele
menti che la compongono.
5
Algoritmo 1.2.
I. Leggi: n; al' a2, •.• , an
2. poni m = al;3. ripeti per i = 2, 3, ..., n:
3.1. confronta m con ai' Se m> ai allora: poni m = ai ed esegui 3.2altrimenti: esegui 3.2
3.2. continua il procedimento ripetitivo
4. poni r = m
5. scrivi: r
6. stop.
In questo algoritmo e nel seguito le istruzioni che devono essere ripetute
sono scritte più a destra delle altre ed evidenziate da una doppia numerazione.
Applichiamo l'algoritmo 1.2 per determinare r = min {6, 3, 3, J}. In questo
caso n = 4, al = 6, a2 = 3, a3 = 3, a4 = l costituiscono i dati del problema che
vengono acquisiti con l'esecuzione della prima istruzione. L'istruzione successiva
inizializza il valore di m imponendo m = 6. Le istruzioni 3.1 e 3.2 vengono quindi
eseguite in sequenza tre volte. La prima volta si pone i = 2 ed il confronto pre
visto dall'istruzione 3.1 avviene tra m ed a2 ovvero tra 6 e 3; siccome 6 > 3si modifica il valore di m che diventa 3. La seconda volta si ha i = 3 e, siccome
m ed ~ hanno lo stesso valore, si effettua un altro confronto senza modificare m.Il confronto successivo, l'ultimo, avviene tra m ed a
4ovvero fra 3 ed l e, siccome
3 > l, si ha m = I. Avendo esaurito il numero di ripetizioni previste dalla istruzione 3. il valore di m rappresenta il risultato ed infatti, con l'istruzione 4., sipone r = m ovvero r = l. Le istruzioni 5. e 6. hanno il significato già visto nel
l'algoritmo 1.1.Si osservi che, specificando n = 3, l'algoritmo 1.2 permette di risolvere il pro
blema posto nell'esempio precedente; esso è quindi più generale dell'algoritmo
1.1.
Esempio 1.3. Assegnati n numeri reali se ne vuol calcolare la somma.
Indichiamo con al' a2, ..., an gli Il valori da sommare. Supponendo n> 2, iln
risultato r = 1: a è ottenuto eseguendo successive operazioni di somma tra duei= l l
addendi nel modo seguente: detto s il risultato della somma tra al ed a2 ad esso si
aggiunge a3
ovvero si esegue l'operazione: s + a)' Indicato ancora 1:011 s 11 risul
tato di questa operazione ad esso possiamo sommare a4
e così via fino ad esau
rire tutto il numero di addendi. Basandosi su questo procedimento si può allora
scrivere il seguente algoritmo in cui, ripetiamo, si suppone n> 2.
I
~
I
6
Algoritmo 1.3.1. Leggi: n; al' a2, ... , an
2. poni s = al + a23. ripeti per i = 3, 4, ... , n:
3.1. poni m = s + ai
3.2. poni s = m
4. poni r = s
5. scrivi: r
6. stop.
nSi osservi che, qualunque sia n, la quantità r = ~ a. può essere pensata come
i= l I n
il risultato della somma di due addendi, uno uguale a zero e l'altro uguale a ~ ai'i=l
Usando questa osservazione è allora possibile scrivere un algoritmo più generale
del precedente in quanto applicabile qualunque sia il numero n di addendi.
Algoritmo 1.4.
l. Leggi: n; al' a2, •.• , an
2. poni s = O
3. ripeti per i = I, 2, ... , n:
3. 1.poni m = s + ai
3.2.poni s = m
4. poni r = s
5. scrivi: r
6. stop.
Esempio 1.4. Assegnati n numeri reali se ne vuoI calcolare il prodotto.
Se al' a2' ... , an
rappresentano i valori dati, considerazioni analoghe a quelle
svolte nell'esempio precedente permettono di scrivere il seguente algoritmo ap-n
plicabile per calcolare r = n a. qualunque sia il numero n dei fattori.i= l I
Algoritmo 1.5.
l. Leggi: n; al' a2, .• " an
2. poni p = l
3. ripeti per i = 1,2, ... , n:
3.l.poni m = p' ai
3.2.poni p = m
4. poni r = p
5. scrivi: r
6. stop.
7
Esempio 1.5. Si vuoi determinare il massimo ed il minimo fra n numeri reali as
segnati.Indicati con a) . a2•... , a
ngli n numeri dati si tratta di scrivere un algoritmo
il cui risultato è costituito dalla coppia di valori R = max {a i ed r = min {a l·l <;; i <; n I l <; i .. n I
Tenendo presente le considerazioni svolte nell'esempio 1.2 ed osservando che R
può essere determinato con un procedimento analogo a quello descritto per il
calcolo di r, si giunge al seguente algoritmo.
Algoritmo 1.6.
l. Leggi: n; al' a2, .•. , an
2. poni m = al
3. ripeti per i = 2, 3, ... , n:
3.1. confronta m con ai' Se m > ai allora: poni m = ai ed esegui 3.2
altrimenti: esegui 3.2
3.2. continua il procedimento ripetitivo
4. poni r = m
5. scrivi: r
6. poni m = al
7. ripeti per i = 2,3, ... , n:
7.1. confronta m con ai' Se m > ai allora: esegui 7.2
altrimenti: poni m = ai ed esegui 7.2
7.2. continua il procedimento ripetitivo
8. poni R = m
9. scrivi: R
lO. stop.
L'impostazione data al problema ha portato ad un algoritmo chiaramente di
visibile in due parti: la determinazione di r, che avviene con l'esecuzione delle
prime cinque istruzioni, e quella di R che avviene dalla sesta istruzione in poi.
Si osservi inoltre che per portare a termine questo procedimento sono necessari
2( n - l) confronti e che l'unica differenza, per altro fondamentale, tra la prima
e la seconda parte si presenta al momento del confronto tra m ed ai' Quando non
si abbia interesse a mantenere nettamente distinte la determinazione di R da
quella di r è possibile risolvere lo stesso problema utilizzando un altro algoritmo
che prevede meno confronti del precedente.
Algoritmo l. 7.
l. Leggi: n; al' a2, · . " an
2. poni m = al
3. poni M = al
4. ripeti per i = 2, 3, ... , n:
8 9
Questo modo di affrontare la soluzione di un problema mediante la scomposi
zione in sottoproblemi è quello comunemente usato nella pratica e sta alla base
della tecnica nota come programmazione strutturata «(1D.
1.2. II linguaggio dei diagrammi a blocchi
La descrizione discorsiva adottata fino ad ora per la formulazione degli algo
ritmi è sicuramente la più naturale. Essa, però, può non essere sufficiente a
descrivere con la dovuta chiarezza le azioni che devono essere compiute e sicura
mente non consente una immediata visualizzazione del flusso dell'algoritmo.
Adoperando opportuni simboli per rappresentare le istruzioni e la loro succes
sione, è possibile descrivere graficamente un algoritmo mettendone in evidenza
i singoli comandi e le loro interrelazioni. Tale descrizione grafica, detta diagramma a blocchi. è realizzata mediante una concatenazione di simboli (blocchi)che, di solito, hanno forma diversa a seconda del tipo di istruzione da essi indi
cata. Dentro ciascun simbolo vengono poi descritte le azioni che devono essere
compiute dall'esecutore dell'algoritmo. I blocchi più comunemente usati e le
operazioni che essi indicano sono i seguenti:
simbolo terminale. Rappresenta il punto in cui un algo
ritmo inizia (start) o finisce (stop);)c__
Come si vede anche dall'esempio precedente, la risoluzione di un problema
può essere effettuata mediante algoritmi diversi ciascuno dei quali corrisponde
ad una diversa analisi del problema e del procedimento risolutivo. Si osservi
inoltre che di solito è utile determinare la soluzione di un problema mediante
quella di opportuni sottoproblemi per i quali sia disponibile un algoritmo.
4.1. confronta m con ai' Se m> ai allora: poni m = ai ed esegui 4.3altrimenti: esegui 4.2
4.2. confronta Mcon ai' Se M < ai allora: poni M = ai ed esegui 4.3
altrimenti: esegui 4.3
4.3. continua il procedimento ripetitivo
5. poni r = m
6. poni R = M
7. scrivi: r ed R
8. stop.
Esempio 1.6. Assegnati n numeri reali positivi che indichiamo con al' a2 , ... , an
si vuoI calcolare l'area del quadrato che ha come lato la loro media aritmetica.
Indicata con m la media aritmetica degli n valori dati, il risultato è rappresen
tato dal valore r = m2. Una prima analisi del problema conduce quindi al seguente
algoritmo:
Algoritmo 1.8.
I. Leggi: n; al' a2, ... , an I n
2. calcola la media aritmetica m =- I: ain i= l
3. poni r = m2
4. scrivi: r
5. stop./
simbolo di direzione. Indica il flusso dell'algoritmo
collegando tra loro tutti i blocchi;
simbolo di ingresso/uscita. Rappresenta il punto in cui
viene acquisito l'insieme dei dati (operazione di ingres
so) oppure viene fornito il risultato (operazione di u
scita);
la cui esecuzione presuppone la possibilità di utilizzare un altro algoritmo per cal
colare il valore m come indicato dall'istruzione 2. Supponendo disponibile l'al
goritmo che permette di calcolare la somma di n numeri si ottiene la formula
zione seguente:
Algoritmo 1.9.
I. Leggi: n; al' a2, .•• , ann
2. calcola s = I: aii= l
3. poni m = sin4. poni r = m2
5. scrivi: r6. stop.
Intestazione
simbolo di decisione. Viene usato per indicare un punto
da cui, in base al verificarsi o meno della condizione spe
cificata al suo interno, è possibile passare all'esecuzione
di parti distinte dell'algoritmo. Se la condizione risulta
vera il flusso procede nella direzione indicata da V, altri
menti in quella indicata da F;
simbolo di ripetizione. Viene usato per indicare che le
operazioni in esso descritte vanno ripetute secondo le
specifiche date nella intestazione;
simbolo di operazione, Viene usato per descrivere ope
razioni di qualsiasi natura diversa dalle precedenti;
IOIl
L 'operazione di assegnazione corrispondente alla locuzione «poni J! = e» èindicata con la scrittura: v+- e.
Per esemplificare come si utilizza il formalismo dei diagrammi a blocchi si ri
porta in fig. 1.1 la descrizione, mediante questo linguaggio, dell'algoritmo 1.1,
in fig. 1.2 quella dell'algoritmo 1.2 ed in fig. 1.3 quella dell'algoritmo 1.7. Dal-
per i = 2, 3..... n
per i = 2.3 ..... n
F
simboli di connessione. Vengono usati per evidenziare
parti diverse di un algoritmo In modo da potervi fare
riferimento. Se tali parti sono descritte sullo stesso fo
glio di carta si utilizza il primo sim bolo; in caso contrario il secondo.
oo
Figura 1.1. Diagramma a blocchi che descrive un algoritmo per il calcolo dir = min {al' a2• a3}·
Figura 1.2. Diagramma a blocchi chedescrive un algoritmo per il calcolo dir = min {a.}.
I c i c n I
Figura 1.3. Diagramma a blocchi che descrive un algoritmo per il calcolo di r = 1~i~ n{ai} ed
R= max {a.}(cfr. algoritmo 1.7).l''i<n I
Figura 1.5. Diagramma a blocchi che descrive il procedimento risolutivo dell'esempio 1.7.
12
l'esame di queste figure risulta evidente come il linguaggio dei diagrammi a blocchi
permetta di evidenziare il flusso di un algoritmo: mediante il simbolo di direzione
viene infatti chiaramente indicata la sequenza in cui le azioni descritte all'interno
dei singoli blocchi devono essere eseguite. Per questo motivo i diagrammi a bloc
chi sono anche detti diagrammi di flusso.
Si osservi che utilizzando il linguaggio dei diagrammi a blocchi risultano facil
mente individuabili alcune situazioni particolari del tipo indicato in fig. lA.
Queste situazioni che chiameremo cicli iterativi prevedono la ripetizione di una
o più istruzioni in base al verificarsi o meno della condizione specificata nel bloc
co di decisione.
Esempio 1.7. Indicando con Xo ed h due valori reali assegnati e supponendo di
saper valutare la funzione sen x, si vuoi calcolare il valore della funzione f(x) =x sen x nei punti Xi = Xo+ ih, i ~ O, fino a che non si verifichi la condizione
f(x k ) = O per qualche k.
In fig. 1.5 è riportato il diagramma a blocchi di un procedimento che risolve
questo problema. Si osservi che il procedimento termina soltanto se è verificata
la condizione «se x sen x = O»altrimenti esso continua, dopo il blocco di deci
sione. nella direzione indicata da F. In altre parole, se la condizione x sen x = Onon risultasse mai verificata, come ad esempio accadrebbe ponendo Xo= - l ed
h = 0.4, il procedimento non avrebbe mai fine.La presenza di un ciclo iterativo può essere allora «molto pericolosa» perchè
il diagramma di flusso che lo contiene può non rappresentare un algoritmo. Si
tuazioni di questo tipo richiedono quindi una analisi particolare e verranno nuova
mente discusse nel cap. lO.
A conclusione di questo paragrafo va osservato che il linguaggio dei diagrammi
F
13
v
L
F
F
Figura 1.4. Alcuni esempi di ciclo iteranvo,
•
a blocchi ha la seguente fondamentale proprietà: dato un qualunque problema
di natura scientifica o meno che ammetta almeno una soluzione, è possibile co
struire un opportuno diagramma di flusso la cui esecuzione fornisce il risultato
corrispondente ad ogni possibile insieme di dati: questa affermazione, nota come
tesi di Church [2], mette in evidenza il notevole potere descrittivo del formalismo
dei diagrammi a blocchi che, come vedremo nel prossimo capitolo, è servito comemodello per il primo progetto di elaboratore elettronico che diremo elaboratore
convenzionale o alla Von Neumann [3]. D'altra parte, è importante ricordare che
il linguaggio dei diagrammi a blocchi non è l'unico modo per descrivere gli algorit
mi. Diversi altri formalismi sono stati definiti ed utilizzati; tra questi, uno dei
più noti è quello delle funzioni ricorsive le cui caratteristiche sono servite per la
costruzione di particolari elaboratori chiamati LlSP-machines. Esistono inoltre
diversi linguaggi oggi abbastanza diffusi quali il LlSP [4], l'Algol [5), il Pascal [6]
che, pur realizzati su elaboratori convenzionali, si basano sul concetto di ricorsivi-
14 15
Esempio 1.9. La funzione differenza di due interi m ed n con n ~ O è definita
dalle due equazioni:tà. Pertanto, anche se il linguaggio FORTRAN oggetto di questo testo non con
sente l'uso di costrutti ricorsivi, riteniamo opportuno concludere questo capitolo
esponendo i concetti fondamentali del formalismo ricorsivo sia per completezza
di esposizione che per l'attualità di questo argomento.(I)
(2)
diff (m, O) = m
diff(m. n) = pred (dìff Irn. pred (n))).
Esempio 1.8. Supponiamo di saper calcolare le funzioni primitive successore di
un intero n, succ(n) = n + l, e predecessore di un intero n, pred(n) = n - l.
Possiamo allora definire la funzione somma di due interi non negativi m ed n,
som (m, n), con le due seguenti equazioni:
1.3. Il linguaggio delle funzioni ricorsive ([7))
E' possibile definire in modo non formale una funzione ricorsiva tramite la
seguente definizione: una funzione si dice ricorsi va se nella sua definizione si fa
uso delle funzioni stesse. Gli esempi che seguono illustrano questo concetto. Esempio 1.10. La funzione prodotto di due interi m ed n ~ O è definita dalle
due equazioni:
Si osservi che nella (2) si è fatto uso della funzione som che supponiamo già
definita (cfr. esempio 1.8), della primitiva pred e di prod stessa.
Calcoliamo prod (3, 2):
prod (m. O) = O
prod (m, n) = som (m, prod (m, pred (n))).
Risulta evidente l'analogia tra questa definizione e quella data nell'esempio
precedente per la funzione som; le due definizioni differiscono esclusivamente per
il fatto che una usa la funzione primitiva pred e l'altra succo
(I)
(2)
som (m, O) = m
som (m, n) = su cc (som (m, pred (n»)
(I)
(2)
Tale calcolo viene detto riduzione; abbiamo infatti ridotto l'espressione som (3, 2)
ad una forma equivalente non ulteriormente riducibile, S, servendoci delle due
equazioni definitorie.
L'equazione (I) dice che la somma tra un intero m e O vale m; questa è la
parte non ricorsiva della definizione la cui presenza è sempre necessaria per assi
curare la fine del calcolo.
L'equazione (2) dice che la somma di due interi m ed n, con n ovviamente
diverso da O, è ottenuta tramite l'applicazione della funzione successore al risul
tato della somma fra m e pred (n). La presenza di som (m, pred (n» nel memhro
destro della (2) viene detta chiamata ricorsiva della funzione che stiamo defi
nendo.
Così, ad esempio, il calcolo di som (3, 2) viene eseguito servendosi delle due
equazioni nel modo seguente:
Esempio 1.11. Datala lista x di elementi al' a2, .•• , an essa viene comunemente
indicata come la l, a2, ... , anI; è possibile evidenziare il primo ed i restanti ele
menti di x usando la notazione [ali z] dove z = [a 2, a 3, ... , anI e I è l'operatore
costruttore di lista tale che [al I[a 2, a3, ... , anll = [al' a2, ... , aJ Se l'insieme
cui appartengono gli elementi della lista x è quello dei numeri reali è possibile
calcolare il minimo tra gli elementi di x mediante la funzione ricorsiva min defini
ta dalle seguenti equazioni:
prod (3,2) = som (3, prod (3, pred (2)))
= som (3, prod (3, I)
= som (3, som (3, prod (3, pred (I)))
= som (3, som (3, prod (3, O»= som (3, som (3, O»= som (3, 3)
=6
perla(2)
calcolando pred (2)
perla(2)
calcolando pred ( I)
per la (1)
calcolando som (3,01
calcolando som (3,3)
min ([al]) = al
min ([al' a2]) = al se al < a2
min ([al' a2 ]) = a2 se al ~ a2
min ([ali z]) = min ([al' min (zj l)
(1)
(2)
(3)
(4)
perla(2)
calcolando pred (2)
per la (2)
calcolando pred ( I)
per la (1)
calcolando succ (3)
calcolando succ (4)
som (3, 2) = succ (sorn (3, pred (2»)
= succ (som (3, I»= succ (succ(som (3, pred (1)))
= succ (succ (sorn (3, O»= succ (succ (3»= succ (4)
=5
16
Così il minimo della lista [2, 4, 1,8) è dato da:
17
min ([2, 4, 1,8» = min ([2, min [4, 1,811)= min ([2, min ([4, min [1,8»»))
= min ([2, min ([4, mn= min ([2, l))
= l
per la (4)
perla (4)
per la (2)
per la (3)
per la (3)
min ([al' a2]) = se al < a2 allora al altrimenti a2
min ([ali z]) = min ([al' min (z l])
Alternativamente, è possibile definire la funzione min usando una sola equa
zione:
Si osservi che se gli elementi di x sono lettere dell'alfabeto, la funzione min
permette di determinare l'elemento di x che precede tutti gli altri nell'ordina
mento alfabetico indicato ancora con il simbolo <.
In generale, è possibile definire una funzione ricorsiva f mediante un numero
finito n di equazioni del tipo:
f(~I) = hl(~l)
f(~2) = h2(~2)
min(x) = se x = [al) allora al altrimenti
se x = [al' a2) allora se al <": allora al altrimenti a2altrimenti
se x = [ali z) allora min (Ia l , mint z j ])
altrimenti «errore».
dove con «errore» si intende la segnalazione del fatto che x non è una lista e quin
di non appartiene al dominio di definizione della funzione min.
In questa definizione glI x) = al ed Hlf(x) è costituita da tutto quello che
segue il primo altrimenti.
Esempio J. J4. Ricordando che la funzione fattoriale di un intero n ~ O è defini
ta come:dove ~i' i = l, 2, ... , n sono elementi del dominio di f e hi' l E;;; i E;;; n. sono com
posizioni di funzioni primitive e/o predefinite ciascuna delle quali può essere
costruita tramite il seguente schema condizionale:n! = In! = n( n ~ I) (n - 2) . . . 2. 1
se n = O
se n> O
si deduce facilmente la seguente definizione ricorsiva:
Dagli esempi risulta evidente che l'uso di più equazioni rende più leggibile
la definizione di una funzione ricorsiva. D'altra parte. ogni funzione ricorsiva
può essere sempre definita in modo estremamente compatto mediante una sola
equazione nella quale si usano opportune condizioni per individuare la forma del
parametro e quindi la funzione da applicare. Va osservato che per descrivere fun
zioni in forma ricorsiva non si fa uso del concetto di assegnazione.
E' possibile dimostrare che il linguaggio dei diagrammi a blocchi e quello delle
funzioni ricorsive sono equivalenti nel senso che ogni funzione è descrivibile sia
In questo schema c indica una condizione ovvero una espressione costruita
tramite funzioni e relazioni primitive o predefinite il cui risultato è un valore lo
gico: vero oppure falso; gj è una funzione primitiva o predefinita ed H/ è una
combinazione di funzioni primitive e/o predefinite eventualmente legate dallo
schema condizionale fra le quali può figurare la funzione f.
Quanto detto viene chiarito dagli esempi seguenti dove ovunque compaia la
funzione identità id definita come id(x) = x per ogni x, conveniamo di scrivere
x in luogo di id(x) ed ancora, ovunque occorra la funzione costante k definita
da k(x) = k per ogni x, conveniamo di scrivere k in luogo dik(x).
Esempio J. J2. Scriviamo in forma generale la funzione ricorsiva som già vista
nell'esempio 1.8
som (m, n) = se n = Oallora m altrimenti succ (som (m, pred (n»)
Esempio J. J3. La funzione ricorsiva min considerata nell'esempio 1.11 può essere
definita dalle seguenti equazioni:
-
(I)
(2)
ovvero:
tattt O) = I
fatt(n) = prod(n, fatt (pre dt nj))
fatt(n) = se n = O al/ora l
altrimenti prodt n, fatt(pred(n))
18
con l'uno che con l'altro linguaggio [8]. La prova di questa equivalenza è data
in modo costruttivo: si può costruire una funzione che traduce ogni algoritmo
descritto in un linguaggio in un algoritmo per risolvere lo stesso problema scritto
nell'altro linguaggio. L'equivalenza può essere dimostrata anche costruendo una
funzione di interpretazione di ogni algoritmo descritto in uno dei due linguaggi.
Siccome i concetti di traduzione ed interpretazione verranno trattati anche nel
cap. 2 a proposito della realizzazione dei linguaggi simbolici di programmazione,
conviene qui precisare i due concetti da un punto di vista puramente funzio
nale.
Siano M ed N due linguaggi; data una qualunque funzione f, siano fM ed fN le
descrizioni di f nel linguaggio M ed N rispettivamente.
Definizione l. Si dice traduttore da M ad N una funzione T tale che per ogni
funzione fMvalga la seguente proprietà:
Il traduttore deve essere quindi tale da produrre una descrizione di f nel lin
guaggio N che rappresenti una funzione equivalente ad fM' In particolare il tra
duttore T può essere scritto nel linguaggio M oppure N ottenendo TM o T N
rispettivamente.
Definizione 2. Un interpretatore per il linguaggio M è una funzione I tale che per
ogni funzione fM e per ogni i del dominio di definizione di f si ha
Ossia I è una funzione che applicata alla coppia (fM' i) produce il medesimo
risultato che si sarebbe ottenuto applicando direttamente fM ad i. L'interpretaioreI può essere scritto usando uno dei due linguaggi M oppure N ottenendo rispetti
vamente 1Med IN'
L'equivalenza fra il linguaggio dei diagrammi a blocchi. B, e quello delle fun
zioni ricorsive, R, è allora dimostrata in modo costruttivo definendo una delle
seguenti funzioni:
• il traduttore TB che associa ad un algoritmo scritto in R, fR, un algoritmo equi
valente scritto in B, fB ;
• il traduttore T R che associa ad un algoritmo scritto in B, fB, un algoritmo equi
valente scritto in R, fR ;
• l'interpretatore IB di algoritmi scritti in K;
• l'interpretatore IR di algoritmi scritti in B.
Notiamo che l'equivalenza tra i vari sistemi formali, in particolare tra R e B,
19
costituisce l'argomento principale che suffraga la tesi di Church già ricordata
nel paragrafo precedente; definendo infatti formalismi «abbastanza lontani»
tra loro si giunge comunque a poter descrivere la medesima classe di funzioni
che viene per questo detta classe delle funzioni calcolabili.
2Dal linguaggio macchina alla realizzazionedei linguaggi simbolici
2.1. Introduzione
La risoluzione di un problema presuppone la definizione di un algoritmo che,
in modo esplicito e non ambiguo, permette di ottenere dai dati iniziali il risultato.
Nella pratica, il compito di eseguire un algoritmo è affidato agli elaboratori elet
tronici (calcolatori) ovvero a macchine costruite proprio per eseguire in modo
automatico le operazioni richieste da un algoritmo.
L'utilizzazione di un elaboratore per l'esecuzione di un algoritmo impone che
tutte le informazioni indispensabili per ottenere il risultato siano fomite alla
macchina in forma ad essa comprensibile ed in particolare devono essere oppor
tunamente formulate le istruzioni che costituiscono l'algoritmo.
In generale diremo unità di programma la formulazione di un algoritmo in un
linguaggio comprensibile ad un elaboratore elettronico (linguaggio di program
mazione). Quando la soluzione di un problema è determinata utilizzando quella
di opportuni sottoproblerni, l'algoritmo che permette di calcolarla è composto da
più algoritmi: quelli che risolvono i sottoproblemi e quello che, utilizzando
i precedenti, permetta la risoluzione del problema dato (cfr. esempio 1.6). Nel
seguito diremo programma l'insieme delle unità di programma che descrivono,
con un linguaggio di programmazione, gli algoritmi necessari alla risoluzione di
un problema.
Un elaboratore è fisicamente costituito da più componenti (unità hardware)
il cui funzionamento presuppone l'utilizzazione di un insieme di programmi che
vengono forniti dalla casa costruttrice e che costituiscono il software di base
dell' elaboratore.
In questo capitolo. dopo una breve descrizione delle caratteristiche hardware
comuni a tutti gli elaboratori convenzionali. sono messe in evidenza le principali
caratteristiche dei linguaggi di programmazione e sottolineate le fondamentali
differenze tra un «linguaggio macchina» ed un «linguaggio simbolico». Dopo la
descrizione delle modalità di realizzazione di un linguaggio simbolico, il capitolo
si chiude con un breve cenno alle caratteristiche essenziali del sistema operativo.
,...
22 23
Figura 2.1. Schema di funzionamento di un elaboratore.
Esempio 2.1. Supponiamo di lavorare con un elaboratore che riserva 8 bits per la
codifica del codice operativo e 8 bits per quella dell'indirizzo. Supponiamo inol
tre che l'esecuzione delle operazioni aritmetiche avvenga utilizzando una parti
colare cella dell'unità aritmetica detta accumulatore in cui si memorizza un ope
rando prima dell'esecuzione dell'operazione e il risultato una volta che I'operazio-
Unità diuscita
Unità di controlloUnità diingresso
codice operativo indirizzo
dove codice operativo identifica l'azione che si vuole venga eseguita ed indirizzo
indica la cella su cui operare. Sia il codice operativo che l'indirizzo sono costi
tuiti da un prefissato numero di bits. Le istruzioni del tipo ora considerato sono
dette ad Wl indirizzo.
2.3. Il linguaggio macchina
Per ogni elaboratore esiste un msierne di istruzioni che devono essere scritte
secondo regole sintattiche fissate e che l'unità di controllo sa interpretare ed
eseguire; tale insieme costituisce il linguaggio macchina. Ogni programma che
debba essere eseguito direttamente dalla macchina deve essere scritto in tale
linguaggio. In pratica ogni elaboratore ha il suo linguaggio macchina che è stretta
mente legato alle caratteristiche dell'hardware.
D'altra parte però. per qualunque elaboratore, gli unici segni disponibili per
formare le istruzioni del linguaggio macchina sono «O» e «I ». Tenendo pre
sente che un qualunque programma in linguaggio macchina è costituito da istru
zioni di tipo diverso (quali ad esempio quelle aritmetiche. di assegnazione. di in
gresso/uscita e di controllo) ciascuna di esse deve essere opportunamente codi
ficata per distinguerla da tutte le altre. In generale pgni istruzione è codificata
su un ugual numero di bits,
Le istruzioni hanno una struttura sin tattica molto elementare quale ad esem
pio la seguente:
2.2. Unità hardware di un elaboratore convenzionale
Le componenti hardware fondamentali per un qualsiasi sistema di calcolo
sono le seguenti:
• unità di ingresso che è un organo che permette di ricevere dall'esterno i dati
iniziali e la sequenza delle istruzioni;
• unità di memoria che è un organo capace di conservare informazioni e di for
nirne, su richiesta. una copia;
• unità di controllo che è un organo che permette di interpretare e far eseguire
la sequenza delle istruzioni;
• unità aritmetica che è un organo che permette di eseguire operazioni sia arit
metiche che logiche;
• unità di uscita che è un organo che permette di comunicare all'esterno i ri
sultati.
Le componenti hardware più comunemente usate come supporti per le unità
di ingresso e di uscita sono videoterminali, stampanti, nastri magnetici, dischi,
dischetti (floppy disks); alcune delle quali possono essere usate anche per la me
morizzazione delle informazioni e quindi possono essere viste come estensioni
delle unità di memoria imemoria di massa o ausiliarie). _La memoria è fisicamente costituita da un insieme di elementi, ciascuno dei
quali può assumere due soli stati fisici rappresentabili dai simboli «O» ed «I».
Dalle caratteristiche fisiche degli elementi che costituiscono l'unità di memoria,
segue che le informazioni elaborabili da un calcolatore devono essere rappresenta
te con una sequenza finita di cifre binarie ciascuna delle quali viene chiamata
bit (hinary digir). Per tutte le applicazioni pratiche il bit è una unità troppo pic
cola di informazione e per questo si considera spesso come unità di informazione
il byte che corrisponde ad un raggruppamento di 8 bits. Un byte è per esempio
sufficiente a codificare i caratteri dell'alfabeto (cfr. cap. 12).
Per rappresentare quantità numeriche si considerano come unità di informa
zione raggruppamenti di un numero fissato di bits. Tali raggruppamenti. ciascuno
dei quali contiene un'unica informazione. prendono il nome di unità di memorianumeriche e la loro lunghezza può variare da elaboratore ad elaboratore. Nel segui
to il termine locazione o cella verrà usato per indicare un raggruppamento di unità
di informazione (numeriche o meno) a cui è associato un numero detto indirizzo.L'indirizzo permette di individuare la posizione di una cella nella memoria secon
do modalità strettamente dipendenti dalle caratteristiche dell'elaboratore usato.
In fig. 2.1 è schematizzato il funzionamento di un elaboratore; le frecce a tratto
continuo denotano una trasmissione di informazioni e quelle tratteggiate l'azione
di controllo.
24 25
ne sia stata eseguita. Sia 000000 IO il codice operativo per l'operazione di cari
camento ovvero per l'assegnazione del valore contenuto in una cella all'accumula
tore; sia 000000 Il il codice operativo per l'operazione di memorizzazione ossia
per l'assegnazione del contenuto dell'accumulatore ad una assegnata cella; sia
inoltre 00000001 il codice operativo per l'operazione di addizione. Consideriamo
le seguenti istruzioni
soprattutto poco leggibili. Essi inoltre non sono porta bili, ovvero non sono tra
sferibili da un elaboratore ad un altro che abbia caratteristiche costruttive diverse.Si osservi infine che la scrittura di un programma in linguaggio macchina richiedela conoscenza degli indirizzi dei dati e delle istruzioni per potervi far riferimento
all'interno delle istruzioni stesse.
0000001000001000
0000000100001001
0000001100001010
Tenendo presente il significato dei codici operativi, l'effetto dell'esecuzionesequenziale di queste istruzioni è il seguente: con la prima istruzione si carica nel
l'accumulatore il contenuto della cella di indirizzo 00001000, con la secondaistruzione si somma al contenuto dell'accumulatore quello della cella di indirizzo 00001001, infine con la terza istruzione si memorizza il contenuto dell'ac
cumulatore nella cella di indirizzo 0000 lOl O. Supponendo che nelle celle di indirizzi 00001000 e 00001001 siano rappresentati i numeri 2 e 3 rispettivamente,l'esecuzione delle istruzioni precedenti implica le trasformazioni descritte in
fig. 2.2 dove r(i) indica la rappresentazione in memoria del numero i.
2.4. I linguaggi simbolici
Le difficoltà legate all'uso del linguaggio macchina sono superate con l'intro
duzione dei linguaggi simbolici di programmazione. Ci occuperemo in questo pa
ragrafo della struttura e dei principi fondamentali dei linguaggi simbolici che si
basano sul linguaggio dei diagrammi a blocchi. Non verranno invece trattati altri
esempi di linguaggi simbolici, quali ad esempio quelli basati sullo schema delle
funzioni ricorsive; tali linguaggi si dicono linguaggi funzionali e sono profonda
mente diversi dai precedenti.In un linguaggio simbolico i codici operativi sono sigle mnemoniche quali ad
esempio LOAD, ADD, STO, e i riferimenti alle celle di memoria dell'elaboratore
non sono più i loro indirizzi effettivi ma nomi simbolici chiamati anche etichette.
In generale i prograrnrru 1I1 uuguaggio macchina risultano molto lunghi e
Figura 2.2. Calcolo di 2 + 3 mediante le istruzioni dell'esempio 2.1.
hanno lo stesso effetto delle istruzioni del linguaggio macchina usate nell'esempio2.1.
A
PESOXYl
LOADADDSTO
I linguaggi simbolici si dividono in due grandi gruppi: quelli assemblativi (o ditipo assem bly) le cui istruzioni sono in corrispondenza biunivoca con quelle del
linguaggio macchina, e quelli compilativi ed interpretativi per i quali tale corri
spondenza non è prevista e che sono progettati con lo scopo di facilitare la stesura
dei programmi. Ovviamente, per eseguire un programma scritto in un linguaggio
simbolico, occorre che esso sia «tradotto» nel linguaggio macchina o «direttamente interpretato».
Si chiama traduttore di un linguaggio L per un elaboratore M un programmache, ricevenuo in ingresso un qualsiasi programma sintatticamente corretto scritto
Esempio 2.2. Siano LOAp, ADD eS'I'O i codici operativi che un linguaggio sim
bolico utilizza per indicare rispettivamente le operazioni di caricamento, aòdi~t'?~
ne- e mernorizzazione. Se supponiamo di associare i nomi simbolici A, PESO,XY l alle celle che nell'esempio 2.1 sono identificate dagli indirizzi 0000 l 000,
0000 l 00 l, 0000 lO lO, le seguenti istruzioni sim boliche
Accumulatore
r(5)
00001010
r(3 )
r(3)
r(3)
r(3)
00001001
r(2)
r(2)
r(2)
r(2)
00001000
Dopo la 3a
istruzione
Dopo la 2a
istruzione
Dopo la l aistruzione
Stato iniziale
26 27
nel linguaggio L (programma sorgente) è in grado di produrre in uscita il pro
gramma equivalente scritto nel linguaggio macchina di M (programma oggetto).
I La traduzione avviene generalmente in due fasi: la prima è nota come costruzione: della tavola dei simboli e l'altra come produzione del programma oggetto.
Nella tavola dei simboli ad ogni nome simbolico incontrato durante la scansione
del programma viene associato l'indirizzo relativo della cella da essa individuata
ovvero la sua posizione riferita alla cella di indirizzo zero dove si pensa sia memo
rizzata la traduzione della prima istruzione del programma. In generale la tavola dei
simboli contiene anche altre informazioni riguardanti il contenuto della cella.
Nella fase di produzione del programma oggetto vengono sostituiti ai codici
operativi mnemonici i corrispondenti codici binari e, grazie alla tavola dei sim
boli, ai nomi simbolici vengono sostituiti gli indirizzi relativi loro associati.
In caso di errori sin tattici nel programma sorgente, il traduttore generalmente
non crea il programma oggetto ma fornisce un elenco di tali errori e la loro posi
zione nel programma; questa eventualità è nota come produzione del diagnostico.I programmi traduttori relativi a linguaggi di tipo assembly si dicono assembla
!2r:.imentre quelli relativi a linguaggi di tipo compilativo si dicono compilatori.La traduzione di un programma scritto in un linguaggio compilativo può avve
nire. per esempio, secondo lo schema riportato in fig. 2.3 nella quale il compi
latore è realizzato mediante la coppia traduttore-assem blatore. In questo caso il
traduttore permette di passare dal programma sorgente ad un programma equi
valente scritto nel linguaggio assembly dell'elaboratore usato e l'assemblatore
fornisce successivamente il programma oggetto scritto in linguaggio macchina.
D'altra parte è opportuno ricordare che esistono compilatori che non prevedono
l'uso di un assemblatore ed eseguono una traduzione diretta in linguaggio mac
china.
LOOP LOAD B
ADD A
456
Indirizzo
relativo
ABA
BIC
C
LOAD ABA
ADD BIC
STO C
STOP
ABA DC 7
BIC DC 8C DC *
END
Nome
simbolico
sono costituite da un'etichetta seguita da un codice operativo simbolico e da
un'altra etichetta che indica la cella di memoria interessata dall'operazione o un
valore quale ad esempio una costante numerica. La prima e la seconda etichetta
possono eventualmente mancare.
Così, ad esempio, nelle istruzioni
LOAD ed ADD sono codici operativi mentre LOOP. A e B sono etichette. Con
sideriamo il seguente programma:
dove i codici operativi LOAD, ADD, STO sono quelli definiti nell'esempio 2.2,
mentre il codice operativo DC indica l'operazione di definizione di costante, che
consiste nel memorizzare nella cella di memoria individuata dalla etichetta che
compare alla sinistra del codice DC il valore specificato alla sua destra: se tale valo
re è * !'istruzione non modifica il contenuto preesistente nella cella stessa. Suppo
nendo che la traduzione di ogni istruzione sia contenuta in una cella e che durante
la costruzione della tavola dei sim boli si associ un indirizzo relativo ad ogni eti
chetta incontrata alla sinistra di ogni codice operativo. la tavola dei sim boli ri
sulta la seguente:Programma
assemblyTraduttore
Assemblatore
I \
i;
Figura 2.3. Un possibile schema di compilazione.
AI nne di illustrare brevemente il funzionamento di un asse m blatore conside
riamo il seguente esempio.
Se i codici operativi LOAD. ADD e STO hanno la codifica binaria considerat a
nell'esempio 2.1 e se il codice della istruzione STOP è 00000000. il programma
oggetto è il seguente:
Esempio 2.3. Supponiamo di utilizzare un linguaggio assemblativo le cui istruzioni
Si osservi che i numeri binari 100, 101, 110, 111, 1000 sono i corrispondenti
delle costanti decimali 4, 5, 6, 7, 8. L'istruzione END ha lo scopo di indicare
la fine fisica del programma e pertanto non viene tradotta.
2.5. La realizzazione di un linguaggio simbolico
Con il termine realizzazione di un linguaggio simbolico si vuoi tradurre il ter
mine inglese implementation con il quale si intendono le modalità che vengono
seguite per arrivare all'esecuzione di un programma scritto In quel linguaggio.
Due possibili schemi di realizzazione sono quello basato sulla traduzione e quello
basato sulla interpretazione.
28
Indirizzo
ol
2345
6
contenuto
0000001000000100
0000000100000101
0000001100000110
0000000000000000
0000000000000111
0000000000001000
non definito
29
Compilatoreo assemblatore
Linker
Dati
Realizzazione mediante traduzione
Ricordiamo che un programma sorgente può essere costituito da una o più
unità di programma. Nella realizzazione di un linguaggio simbolico mediante
traduzione ogni unità di programma viene separatamente tradotta in una oppor
tuna successione di istruzioni del linguaggio macchina (modulo oggetto) cui è
associa ta la sua tavola dei sim boli.Il programma oggetto risulta quindi costituito dall'insieme dei moduli oggetto.
Per rendere eseguibile il programma sarà necessario sostituire agli indirizzi relati
vi presenti in ciascuna tavola dei simboli gli indirizzi assoluti ovvero quelli deter
minati in base all'indirizzo effettivo della cella a partire dalla quale il programma
verrà memorizzato. Tale compito viene assolto da un opportuno programma
(/inker) che, oltre a determinare gli indirizzi assoluti, crea i necessari collegamenti
tra i diversi moduli oggetto e produce la versione eseguibile del programma tpro
gramma eseguibile). A questo punto può avere inizio la fase di esecuzione, durante
la quale avviene la lettura degli eventuali dati. In fig. 2.4 si riassume il procedi
mento ora descritto.Si osservi che un programma può essere affetto da errori di varia natura:
• errori che vengono segnalati dal diagnostico nella fase di traduzione (errori
sin tattici)
Figura 2.4. Realizzazione di un linguaggio simbolico mediante traduzione.
• errori che vengono segnalati dal linker (per esempio quando venga fatto ri
ferimento ad una unità di programma che non è disponibile);
• errori che vengono segnalati in fase di esecuzione (per esempio si cerca di ese
guire una operazione matematicamente non definita quale a/b con b = O). Questo
tipo di errore è il più difficile ad essere corretto, in quanto sia la sua segnalazione
che la sua individuazione nel programma sorgente dipendono dal software del
l'elaboratore usato;
• errori che non possono essere segnalati (errori logici). In questo caso il pro
gramma sorgente non descrive la soluzione della classe di problemi proposta.
L'assenza di errori di questo tipo può essere in parte garantita tramite la verifica
dei risultati ottenuti per problemi di cui è nota la soluzione.
Realizzazione mediante interpretazione
Un'altra modalità di realizzazione di un linguaggio è quella che utilizza un
~rogramma detto interpretatore, talvolta già realizzato in hardware, come per il
linguaggio BASIC nei personal computers. Un interpretatore è in grado di leggere,
3130
, ~.-..-------------------aq;---_....._-----------
Figura 2.5. Procedimento di interpretazione.
2.6. Il sistema operativo
Le interazioni tra l'utente ed il sistema di calcolo avvengono di solito attraver
so un'interfaccia di tipo software chiamata sistema operativo che consiste nel
l'insieme di quelle procedure che controllano tutte le risorse di tipo hardware
e/o software di una installazione. In ultima analisi un sistema operativo è un in
sieme di programmi tramite i quali si tende ad ottimizzare il tempo di utilizzo
dell'elaboratore e a rendere tale utilizzazione «amichevole» per l'utente.
L'evoluzione dei sistemi operativi è profondamente legata all'evoluzione della
tecnologia degli elaboratori da una parte e alle esigenze degli utenti dall'altra. So
no stati così messi a punto sistemi operativi che seguono filosofie diverse e per
mettono gestioni diverse delle risorse di un sistema di calcolo. Ad esempio i si-
stemi basati sul principio della monoprogrammazione consentono l'elaborazione
sequenziale di più programmi costituenti una sequenza di lavori usualmente me
morizzata su una unità a disco magnetico. Tali sistemi vengono detti di solito
«Disk operating systerns» (DOS). A differenza dei precedenti i sistemi che usa
no la tecnica della spartizione del tempo (time-sharingv dedicano ciclicamente
tutte le risorse del sistema ad un lavoro per un periodo di tempo prefissato, con
sentendo un'elaborazione pseudo-parallela dei lavori proposti da più utenti.
Un altro tipo di sistema operativo è quello basato sul principio della multipro
grammazione che prevede la presenza di più programmi nell'unità di memoria ed
elahora un programma finchè esso non richiede un'operazione di ingresso/uscita.
Il tempo necessario allo svolgimento di questa operazione. che generalmente è
molto maggiore di quello necessario per eseguire altri tipi di operazioni. viene di
solito sfruttato per iniziare o proseguire l'esecuzione di qualche altro programma
presente in memoria.
I sistemi operativi svolgono le loro operazioni su richiesta degli utenti grazie
ad un programma. il supervisore, che fa parte del sistema operativo stesso. Il su
pervisore è in grado di interpretare un dato insieme di comandi che è caratteristi
co di ogni singolo sistema operativo; ad esempio, per attivare le diverse fasi del
l'elaborazione di un programma quali la compilazione. l'attivazione del linker e
l'esecuzione si devono dare opportuni comandi al supervisore: analogamente
devono essere esplicitamente specificati i comandi che permettono di eseguire
operazioni di correzione, mernorizzazione o cancellazione di programmi e di dati.
I sistemi che prevedono la multiprograrnmazione e/o il tirn e-sharing sono in
stallati su elaboratori che devono soddisfare contemporaneamente più utenti.
Oggi la tecnologia elettronica ha consentito la «personalizzazione» del calcolo,
mettendo a disposizione personal com puters a prezzi accessibili anche a singoli
utenti. di fatto rendendo meno sentita l'esigenza di sofisticati sistemi operativi
nel senso sopra accennato. Anche in un personal computer però. la comunicazione
uomo-macchina avviene tramite il sistema operativo (usualmente di tipo DOS).
Pertanto, qualunque sia il sistema di elaborazione usato. l'utente dovrà aver ac
quisito una certa padronanza del linguaggio di comandi del corrispondente siste
ma operativo.
RisultatiIn terpretatore
Programmasorgente
tradurre ed eseguire, ossia interpretare ciascuna istruzione del programma sor
gente insieme ai dati. In questo caso lo schema realizzativo diventa quello ripor
tato in fig. 2.5.
Il grande vantaggio dell'interpretazione rispetto alla traduzione risiede nel fatto
che gli errori sono segnalati nel momento in cui si verificano con la precisa ed
immediata indicazione dell'istruzione del programma sorgente che li ha provo
cati. Il procedimento dell'interpretazione risulta quindi utilissimo in fase di messa
a punto di un programma in cui è fondamentale un diagnostico più ricco possi
bile.
Ci sono però alcuni svantaggi nell'uso dell'interpretazione rispetto alla tradu
zione. tra i quali più evidente è la maggior lentezza complessiva della elahorazione
(si pensi al caso di un procedimento ripetitivo in cui, ad ogni ripetizione, ciascuna
istruzione deve essere letta, tradotta ed eseguita).
In pratica alcuni nnguaggi sono usualmente realizzati tramite compilazione
(esempi sono il FORTRAN, il COBOL, il PLI) mentre altri, quali il BASIC, l'APL,
il LISP sono di solito realizzati mediante interpretazione.
3Rappresentazione dei numeri
3.1. Numeri interi
II sistema di numerazione a noi più familiare è quello decimale nel quale il
numero IO (dieci) è la base ed i numeri interi O, l, 2...., 9 costituiscono le cifre.
Altri sistemi di numerazione che interessano le applicazioni sono quello binario
che opera con la base 2 (due) e le cui cifre sono costituite dai simboli O e l;
quello ottale che utilizza la base 8 (otto) e le cifre O, 1,2,3,4, 5,6,7; quello
esadecimale che, usando come base il numero 16 (sedici), utilizza come cifre i
simboli O, 1,2,3.4,5,6,7,8,9, A, B, C, D, E, F.
Nel seguito il simbolo N indicherà un numero in base lO mentre (N)~ indicherà
che il numero intero N è rappresentato nella base {3. Se N < <Xl, si ha che
(3.1 )rn
(N)il == ± L ~{3k,k=O
01<00
dove aj , j == O, l, ... ,01 sono cifre del sistema di numerazione in base Il.
Fissato Il, il massimo numero NOlax
rappresenta bile mediante m < 00 cifre è
11m - l.
Conversione in base dieci
Supponendo nota la rappresentazione di N in base Il è possibile trovare la rap-
NOlax
== 9999 == 104 - I
NOlax == ( III 1)2 == 24- Im==41l==2
Esempio 3.1. 1471 == I x 103 + 4 x 102 + 7 x 101 + I x 100
(1471)8 == l x 83 + 4 x 82 + 7 x 8 1 + I x 8°
(1471 )1& == l x 163 + 4 x 162 + 7 x 16 1 + l x 16°
Esempio 3.2. m == 4 Il == lO
Jnz .
34 35
presentazione in base dieci applicando direttamente la (3.1) dove, per comodità
di notazione, le cifre ak e la base {3 vengono espresse in base dieci.
Esempio 3.3. (3471)8 = 3)( 8 3 + 4)( 82 + 7)( 81 + I )( 80 = 1849
(3471)16=3)( 163+4)( 162+7)( 161+ 1)( 160=5845
(AI)16 = 10)( 16' + l )( 160 = 161
( 10)2 = I )( 2' + O )( 20 = 2
(100)2 = l )( 22 + O )( 2' + O )( 20 = 4
(1111)2 = l )( 23 + 1)( 22 + l )( 21 + I )( 20 = 15.
dell'algoritmo descritto sopra dà luogo ai seguenti passi:
i = O No = 37 è dispari ao = I
i= I N = 18 è pari a, = OI
i = 2 N2 = 9 è dispari a2 = I
i = 3 N3 = 4 è pari a3 = O
i = 4 N4 = 2 è pari => a4 = O
i = 5 N = I è dispari => a5 = l5
quindi la rappresentazione binaria del numero 37 è datta dalla successione
Una volta determinate ao ed a" le restanti cifre binarie ak, k = 2, ... , r saran
no ottenute in modo analogo. Si perviene così al seguente algoritmo:
Conversione in binario
Assegnato un intero N in base dieci è possibile ottenere la sua rappresentazio
ne in base (3; in particolare, l'equivalente binario del numero N può essere otte
nuto dalla (3.1) tenendo presente che la cifra ao di un numero binario è zero
se e soltanto se il numero è pari. Allora, indicato con r un intero positivo tale
che 2r.,;;; N < 2r + " si ha:
se m = 32 O~ N .,;;; 231 - I = 2 147483647.
Nm ax
= (OIII ... 1)2 = 2(m - 1) - l;
pertanto è possibile rappresentare con m bits tutti e soli i numeri interi positivi
N tali che O.,;;; N ~ Nmax . In particolare per m = 16 ed m = 32 si hanno le limitazioni seguenti:
Supponendo 2r.,;;; N < 2r + " sia m> r un numero finito e prefissato di cifre
binarie destinate alla rappresentazione di N; evidentemente, tenendo presente la
(3.1), dovrà essere ak = O, (r + l) .,;;; k ~ (m - I). Così per esempio se m = 7 la
rappresentazione binaria di 37 è data da (0100101)2 mentre, fissato m = IO,
si ha (0000100101)2'
Va inoltre osservato che nella rappresentazione di un intero in un elaboratore
vengono usati un numero finito m di bits il primo dei quali indica il segno: tutti
i numeri positivi sono caratterizzati da una rappresentazioni binaria con il primo
bit uguale a zero. Così ad esempio il numero 109 = (110 11O1)2 verrà memoriz
zato, supponendo m = io, come 000 Il OIl OI dove il primo bit (O) indica il
segno (positivo) e le restanti nove cifre contengono la rappresentazione binaria
di 109.
Da quanto detto segue che il massimo numero intero positivo rappresentabile
con m bits di cui il primo riservato al segno è rappresentato dalla cifra O seguitada (m - I) cifre I ovvero
r r
dove No = N = L ak2k = ao + L ak 2k ;k=O k=1
/ I se No è dispari
ao="<,O se No è pari
/ I se N, è dispari
al =""-O se N, è pari
Algoritmo 31.
I. Leggi: N, r
2. poni No = N3. ripeti per i = O, l, ... , r - I
3.1. se N j è dispari allora: poni ai = I ed esegui 3.2
altrimenti: poni ai = O ed esegui 3.2
3.2. poni N j + , = (N j - a j)/2
4. poni ar
= Nr
5. stop.
Esempio 3.4. Vogliamo trovare la rappresentazione binaria di N = 37. Dalla re
lazione 25 ,ç 37 < 26 segue che si devono calcolare 6 cifre binarie. L'applicazioneIl termine overflow indica il tentativo di rappresentare in un elaboratore numeriN>N .max
\~
36
Interi negativi
SI è detto che ogni numero binario positivo è caratterizzato dalla presenza della
cifra O in prima posizione; essendo stato scelto il primo bit a significare il segno,:,ç questo è uguale ad I il numero binario è inteso essere negativo. La presenza del
la cifra l in prima posizione è ottenuta rappresentando i numeri negativi sotto
forma di complemento a due. Si ricordi che si dice complemento a due di un
numero binario rappresentato con m bits la differenza fra quella potenza di 2
che è rappresentata dalla cifra l seguita da m cifre O ed il numero stesso.
Esempio 3.5. Se m = 4 la rappresentazione del numero 5 è O101. Per ottenere
la rappresentazione di - 5 si deve calcolare la differenza (10000)2 - (OlO1)2
che è uguale a (1111)2 - (0101)2 + (0001)2 essendo (10000)2 = (1111)2 +
+ (0001)2' Si osservi che la sottrazione (1111)2 - (0101)2 è facilmente realizzata invertendo logicamente le cifre del sottraendo, ossia sostituendo alla cifra
O una cifra I e viceversa. Si ha allora (10000)2 - (0101)2 = (0101)2 - (0001)2 =
= (1011)2' Il numero (1011)2 è dunque la rappresentazione di - 5 su m = 4 bits.
In pratica, dato un numero binario positivo, ossia con un bit O in prima posizione, si ottiene la rappresentazione del suo opposto invertendo logicamente
le m cifre e quindi sommando 1 al risultato dell'inversione logica. Tutte queste
operazioni su un elaboratore sono facilmente realizzate in hardware.La rappresentazione dei numeri negativi nella forma di complemento a due
consente di unificare le operazioni di addizione e sottrazione e quindi di sempli
ficare l'hardware dell'elaboratore; la rappresentazione della differenza tra due
numeri è infatti uguale alla rappresentazione della somma tra il primo ed il com
plemento a due del secondo.
Esempio 3.6. Sia m = 4; calcoliamo 5 - 2. Questa operazione si può effettuare in
binario come segue:
(OlO1)2 + (10000)2 - (0010)2 - (10000)2 = (Ol O1)2 + (1110)2 - (10000)2 =
= (10011)2 - (1000U)2 = (0011)2 = + 3.
37
(0010)2 + (10000)2 - (0101)2 - (10000)2 = (0010)2 + (1011)2 - (10000)2 =
= (1101)2 - (10000)2 = (- 0011)2'
Anche in questo caso la sottrazione finale (110 1)2 - (10000)2 non viene eseguita: (1101)2 è già il risultato finale in quanto rappresenta il complemento adue di 3 ossia - 3.
I numeri interi negativi N rappresentabili con m < 00 bits nella forma di complemento a due sono tutti e soli quelli per cui - 2(m- 1) ~ N < O. Per m = 16
si ha N ~ - 215 = - 32768 mentre per m = 32 vale la limitazione N ~ - 231 == - 2147483648.
3.2. Numeri reali
Fissata una base di numerazione (3 è possibile rappresentare un qualsiasi numeroreale x finito e diverso da zero nella forma:
(3.2)
dove ai' ~ i ~ m sono cifre del sistema di numerazione usato e b è un interoespresso nella base (3. La rappresentazione (3.2) del numero x è detta in virgola
mobile normalizzata (floating point); le cifre al' a2, ... , am costituiscono lamantissa mentre l'intero b è detto caratteristica.
Esempio 3.8. I numeri decimali
-0.1471 +37.1 -0.0125 +0.003 +300
sono rispettivamente rappresentati in virgola mobile normalizzata come:
-0.147110° +0.371102 -0.12510- 1 +0.310- 2 +0.3103 .
Da quanto detto segue che, indicata con (X)(3 la rappresentazione di un qualsiasi numero reale x diverso da zero in base (3, si ha:
Conversione in binario
Per determinare la rappresentazione binaria di un numero reale x espresso inbase dieci si consideri dapprima il problema di determinare le cifre binarie dellamantissa di un numero decimale x, O < x < l. Dalla relazione:
Si osservi che l'ultima sottrazione di fatto non viene eseguita nella macchina.
Infatti, siccome il numero di bits (m = 4) fissati per la rappresentazione degli
interi è insufficiente a rappresentare il risultato dell' operazione (O101)2 + (1110)2
= (100 Il )2' basterà eliminare il primo bit di tale risultato per tener conto anchedella successiva sottrazione ed ottenere il risultato finale (0011)2'
Esempio 3.7. Sia ancora m = 4; vogliamo calcolare 2 - 5. Si ha:
(3.3)m
(X)(3=±0.a1a2... am(3 b = [aj
(3 i.(3b.j= l
38 39
3.3. Rappresentazione finita ed errori di arrotondamento
Nella pratica le caratteristiche hardware di un elaboratore impongono precise
limitazioni sul numero di cifre utilizzate per la rappresentazione di un numero
e. pertanto, solo un sottoinsieme dei numeri reali può essere rappresentato su un
determinato sistema di calcolo. Più precisamente. indicata con (1 la base di nume
razione usata dall'elaboratore, sia m < 00 il numero di cifre utilizzato per la rnantìssa. n < 00 quello per la caratteristica e siano L ed U rispettivamente il massimo
ed il minimo intero rappresentabile con le n cifre della caratteristica. Se F è l'in
sieme dei numeri reali rappresentabili suU'elaboratore, F è costituito da tutti e
soli i numeri reali x la cui rappresentazione in virgola mobile normalizzata ha una
caratteristica b tale che L ~ b ~ U ed una mantissa costituita al più da m cifre
diverse da zero. Sono pertanto elementi di F sia il numero zero, la cui rappre
sentazione è caratterizzata da ai = O, l ~ i ~ m, che tutti i numeri reali rappre
sentabili nella forma
(3.4) ± O. al a2 · .. am O... O ... (1b, al "* O. L ~ b ~ U.
I valori delle costanti (1, m, L ed U sono dati forniti dalle case costruttrici in
quanto strettamente legati alle caratteristiche hardware dell'elaboratore. La base
di numerazione (1 è generalmente due ma è spesso usato anche il sistema di
numerazione ottale o esadecimale. Le costanti L ed U delimitano l'ordine di
grandezza dei dati rappresentabili su un elaboratore: il tentativo di rappresentare
numeri la cui caratteristica è maggiore di U è detto overflow mentre quello di
rappresentare numeri con caratteristica minore di L è detto underflow. Il signi
ficato del numero m di cifre destinate alla mantissa è strettamente legato alla
«precisione» con cui l'elaboratore lavora. Sia infatti x un numero reale la cui
rappresentazione nel sistema di numerazione usato dall'elaboratore è data da:
(3.5) ± O. al a2 · .. am am + l' .. am + i e», ai "* O, L ~ b ~ U
dove am + i "* O per qualche i > O.Siccome la rappresentazione (3.5) ha una mantissa con cifre diverse da zero
nelle posizioni che seguono la m-esima, il numero x non appartiene ad F e non
può essere rappresentato sull'elaboratore; esso è allora sostituito da una sua ap
prossimazione che indicheremo con fl(x) appartenente ad F. Il valore fl(x) è ot
tenuto da (3.5) per troncamento oppure per arrotondamento; nel primo caso
fl(x) è dato da:
(3.6) fl(x) = ± O.al a2... a
m(1b
nel secondo:
Il1\
segue:
m
2x = al + [ ai 2- (i-l}
i= 2
da cui, posto CI = 2x, si ha: al = l se Cl ~ l, al = O se Cl < l. Analogamente,
posto c2 = 2( CI - al', si ha a2 = l se c2~ l, a2 = O se c2< l. In generale, posto
Ci = 2(c i _ 1- ai_ l)' la i-esima cifra ai della mantissa é data da:
a. =/' l se Ci~ l
I """O se Ci< 1.
Esempio 3.9. Si vuoI determinare la rappresentazione binaria del numero deci
male x == + 0.1. Applicando il procedimento sopra indicato si ottiene:
(+ 0.00011001100110011 .... ')2
ovvero il numero decimale 0.1 non ha una rappresentazione binaria finita in quan
to esso è, in base due, un numero periodico di periodo 00 Il. Si osservi inoltre
che la rappresentazione binaria in virgola mobile normalizzata del numero deci
male x == 0.1 è data da
+ 0.1100110011001100 ... (1101, (1 = (10)2 = 2
essendo 101 la rappresentazione binaria di - 3.
Sia ora x un qualunque numero reale espresso in base dieci. La sua rappre
sentazione binaria è ottenuta convertendo sia la parte intera che quella decimale;
la conversione della parte intera avviene seguendo le regole viste nel paragrafo
precedente mentre quella della parte decimale avviene applicando il procedi
mento di conversione ora descritto.
Esempio 3.10. Tenendo presenti i risultati degli esempi 3.4 e 3.9 si ha che la rap
presentazione binaria del numero decimale + 37.1 è data da
(+ 100\01.000\100110011001\ .. ')2
La rappresentazione binaria in virgola mobile normalizzata di 37.1 è allora:
+ 0.\00\01000\\00\\00\\ ... fflilo. (1 == (10)2 == 2
essendo 0\\ O la rappresentazione binaria di + 6.
(3.7)se am + 1<(1/2
se am + I ~ (1/2
40 41
mentre, se tl(x) è ottenuto da (3.7), valgono le seguenti relazioni:
caratterizzati da valori diversi della costante m: il sistema in precisione semplicee quello in doppia precisione. La denominazione scelta per i due sistemi è legata
al fatto che il numero di bits destinati a rappresentare il numero nel secondo si
stema è il doppio di quello usato nel primo e il passaggio deIIa precisione semplice
a quella doppia implica un aumento della precisione nel senso che, daIIa preci
sione di macchina f m caratteristica della precisione semplice, si passa ad una pre
cisione di macchina minore o uguale di f~. Si osservi che, contrariamente a quan
to avviene per la mantissa, il numero di cifre usate come caratteristica è general
mente lo stesso sia nella semplice che nella doppia precisione.
Quanto detto in questo paragrafo mette in evidenza che in un elaboratore la
rappresentazione di quantità reali non intere non è in generale esatta: essa coin
cide con il valore esatto a meno di una quantità finita, diversa da zero che di
pende dalla precisione di macchina.
Sull'insieme F dei numeri rappresentabili su un elaboratore sono definite le
operazioni elementari di addizione, sottrazione, moltiplicazione e divisione.
Indicata con . una qualunque operazione elementare, sia 8 la corrispondente
operazione definita in F. Il modo con cui 8 viene effettivamente eseguita dipende
dall'elaboratore usato e, in generale, si ha:
x 8 y = tl(x . y) = (x . y) (1 + f), Ie I~ f m
per ogni coppia di valori x ed y appartenenti ad F. La differenza tra x . y e
x 8 y rappresenta l'errore di arrotondamento commesso nell'esecuzione dell'o
perazione e dipende daIIa precisione con cui si opera. Le operazioni di somma e
moltiplicazione definita su F sono generalmente commutative ma non associative
e anche la proprietà distributiva non è più valida quando si usa una aritmeticafinita ovvero quando le operazioni vengono eseguite usando una precisionefinita.
eR = (x - tl( x»/x.
tl(x) = x(l + f),
Si osservi che le limitazioni ottenute per gli errori di arrotondamento dipendo
no dal metodo usato per calcolare flf x): il troncamento può portare ad errori
che possono essere il doppio di quelli che sarebbero stati ottenuti con l'arroton
damento. Va inoltre sottolineato che gli errori relativi, al contrario di quelli
assoluti, non dipendono dalla caratteristica ovvero non dipendono dall'ordine
di grandezza del numero x.Da quanto detto segue che il valore tl(x) ottenuto da (3.5) per troncamento
o per arrotondamento, è tale che
è facilmente verificabile che, quando tl(x) è ottenuto per troncamento da (3.6),
si ha:
eA
= x - tl(x)
ed errore relativo di arrotondamento la quantità
In ogni caso, se x ha una rappresentazione di tipo (3.5) la sostituzione di x con
tl(x) dà luogo ad un errore, detto errore di arrotondamento, il cui valore dipende
dalla tecnica usata per determinare tl(x). In particolare, detta errore assoluto di
arrotondamento la quantità
Vogliamo eseguire queste stesse operazioni utilizzando, nel sistema decimale,
una rappresentazione in virgola mobile normalizzata con m = 4 cifre di mantissasupponendo che tl(x) sia ottenuto per troncamento dal valore di x. In questaipotesi si ha:
(x l Ef) x2 ) mx3
= (0.2000 10° I±J 0.2500 10- 3) Ef) 0.7800 10- 3 =
= (0.2000 10° Ef) 0.0002 100)Ef) 0.7800 10~ 3 =
= 0.2002 10° I±J 0.0007 10° = 0.2009 10°
dove fm
è data da
se tl(x) è calcolato per troncamento
se tl(x) è calcolato per arrotondamento
La quantità fm
è detta precisione di macchina e rappresenta una limitazione
superiore per l'errore relativo di arrotondamento quando al valore x, non esat
tamente rappresentabile sull'elaboratore, si sostituisce la sua approssimazione
tl(x). La precisione di macchina è una quantità caratteristica di ogni elaboratore
e dipende dalla base di numerazione, dal numero di cifre m destinate alla mantissa
e dal metodo scelto per determinare fl(x). La maggior parte dei sistemi di calcolo
permette di utilizzare due diversi sistemi di rappresentazione dei dati numerici
Esempio 3.11. Dati i valori Xl = 0.2, x2 = 0.00025 e x3
(Xl + x2 ) + x3 = Xl + (x 2 + x3 ) = 0.20103.
0.00078 si ha che
•
42
XI(±J (X2
r±l X3)
= 0.2000 10° m(0.2500 10- 3 r±l 0.7800 10- 3) =
= 0.2000 10° l±l 0.1030 10~ 2 =
= 0.2000 10° l±l 0.0010 10° = 0.2010 10°
Il risultato di (Xl mX2) l±l X3 non coincide quindi con quello di xl r±l (X 2 r±l X3):
nel primo caso si è ottenuto un valore che coincide con il risultato esatto a meno
di una quantità dell'ordine di 10- 4, nel secondo l'errore commesso è, al più,
dell' ordine di 10- s.Supponiamo ora di voler sommare i seguenti valori:
Xl = 0.94 10- 4 , X2= 0.26 10- 4 e X
3= 0.1 10°.
Si ha:
(Xl mX2)
r±l X3
= (0.9400 10- 4(±J 0.2600 10- 4) r±l 0.1000 10° =
= 0.120010- 3 I!l 0.100010° =
= 0.000 l 10° r±l 0.1000 10° = 0.100 l 10°
x1(±J (x2
l±l x3)
= 0.9400 10- 4 r±l (0.0000 10° r±l 0.1000 10°) =
= 0.9400 10- 4 r±l 0.1000 10° =
= 0.0000 10° r±l 0.1000 10° = 0.1000 10°.
Il contributo degli addendi xl ed x 2 è completamente ignorato quando la somma
è calcolata aggiungendo il valore di Xl ad x2 I!l x3 .
L'esempio precedente mette in evidenza che, quando si opera in aritmetica
finita, la precisione con cui si determina il risultato, dipende, oltre che dalla pre
cisione di macchina, anche dall'ordine in cui vengono eseguite le operazioni. Inoltre,
formule matematicamente equivalenti possono dare risultati diversi se utilizzate
in precisione finita.
Esempio 3.12. Si vuoi determinare il punto medio xm di un intervallo di cui sono
noti gli estremi a = 0.651 e b = 0.653. Sappiamo che:
X m = (a + b)/2.
Supponendo di utilizzare in base dieci una rappresentazione finita con tre cifredi mantissa si ha:
Il valore calcolato del punto medio non appartiene all'intervallo ed è quindi
,.
43
completamente sbagliato. Avremmo trovato un risultato più corretto se avessimo
usato la relazione:
X m = b + (a - b)/2:
In questo caso il valore calcolato è xm = 0.652. Infatti:
x m = 0.653 10° Hl (0.65 I 10° El 0.653 10°) O 2 =
= 0.653 10° l±l (- 0.200 10- 2) 02 =
= 0.653 10° r±l (- 0.100 10- 2) =
= 0.653 10° r±l (- 0.001 10°) = 0.652 10°.
Lo studio degli errori di arrotondamento e della loro propagazione è di fonda
mentale importanza per una corretta interpretazione dei risultati di un qualunque
algoritmo eseguito in precisione finita. Tale studio esula dagli scopi di questo
testo in quanto più pertinente a testi di calcolo numerico (cfr. [9], [lO), [Il)).
IIIl FORTRAN 77
Il
~I
4Il linguaggio FORTRAN
4.1. Introduzione
La storia del linguaggio FORTRAN inizia nel 1953, quando la IBM dette inizioal progetto di definizione di un sistema di programmazione per l'allora nuovo
elaboratore 704. Tale sistema doveva permettere di superare gli svantaggi insiti
nell'uso del linguaggio assembly, fra cui essenzialmente il costo notevole di analisi
dei problemi scientifici e l'impossibilità di utilizzo da parte dei non specialisti.
Nel novembre 1954 fu così pubblicato il primo rapporto preliminare sul nuovo si
stema, chiamato IBM Mathematical FORmula TRANslation system: FORTRAN.
Il progetto iniziale era rivolto all'utilizzo sul 704, a cui si riferiva il primo compi
latore elaborato nel 1957 e la successiva versione FORTRAN Il; ma il successo
dell'iniziativa fu tale che intorno al 1960 proliferarono versioni del FORTRAN
legate ai diversi elaboratori allora disponibili. Si cominciò allora a sentire l'esi
genza di definire uno standard del linguaggio da poter assumere come base nella
costruzione dei diversi compilatori: un programma scritto secondo le regole di tale
standard sarebbe stato accettato come sintatticamente corretto da tutti i compi
latori conformi allo standard. Un primo passo in tal senso fu compiuto ancora
dalla IBM che nel 1962 pubblicò il cosiddetto FORTRAN IV; ma in quello stesso
anno l'American National Standard Institute (ANSI) affidò ad una commissione
la definizione di uno standard che fu definitivamente pronto nel 1966 e che è
noto come FORTRAN 66 (cfr. [13]).
Dal 1966 in poi, in seguito al rapido evolversi degli elaboratori dal punto di vi
sta dell'hardware e del software, il FORTRAN ha subito grosse trasformazioni.
Nel 1969 l'ANSI decise di formulare un nuovo standard che recepisse le principali e più importanti estensioni del FORTRAN 66 introdotte dai compilatori di
nuova costruzione: la situazione era in così rapida evoluzione che soltanto nel1978 fu approvato il nuovo standard, noto come FORTRAN 77. Il documentoche definisce il FORTRAN 77 [12] descrive due livelli del linguaggio: il Full
Language. detto FORTRAN o FORTRAN 77, ed il Subsct Language che è un
sottoinsieme del Full Language e costituisce lo standard attuale per elahoratori
48
con capacità di memorie limitate. Le differenze principali tra il Full ed il Subset
Language sono riassunte in appendice A l mentre quelle tra il FORTRAN 77 ed
il FORTRAN 66 verranno messe in evidenza nel corso del testo e riassunte in ap
pendice A2.
Nel seguito le sigle F77 ed F66 saranno usate per indicare rispettivamente il
FORTRAN 77 ed il FORTRAN 66.
4.2. Alfabeto
L'insieme dei caratteri FORTRAN ossia l'alfabeto del linguaggio è costituito
da:• caratteri alfanumerici: le cifre del sistema decimale (O, l, 2, 3, 4, S, 6, 7, 8, 9)
e le lettere dell'alfabeto inglese (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q,
R, S, T, U, V, W, X, Y, Z);
• caratteri speciali: = uguale
+ più- meno
* asterisco
sbarra
parentesi tonda aperta
paren tesi tonda chiusa
punto
apice
spaziatura (blank)
$ dollaro
due punti (non previsto in F66).
Si osservi che il carattere blank può essere usato per migliorare la leggibilità
di un programma; infatti esso non ha alcun significato per il compilatore che lo
ignora sempre ad eccezione di casi particolari che verranno evidenziati in seguito.
Per evidenziare la presenza di un carattere blank useremo talvolta il simbolo v.
4.3. Costanti, nomi simbolici, parole chiave
Un programma FORTRAN è costituito da frasi (o istruzioni) scritte con i
caratteri dell'alfabeto FORTRAN e suddivise in una o più unità di programma.
Tra gli elementi primari che costituiscono una istruzione figurano le costanti,
i nomi simbolici e le parole chiave.
Costanti
Una costante FORTRAN è una successione di caratteri che rappresenta per il
49
compilatore un valore che non deve cambiare durante l'esecuzione del program
ma. La forma di una costante verrà definita nel capitolo seguente.
Nomi simbolici
Un nome sirnl!2!i~0 è una successione dicaratteri alfanumerici fh~Qeve !!!iziare
con lJ~~)~~t~!~~ deve essere costituita al più da 6 (sei) caratteri. I nomi simbo'lici sono usati dal programmatore per identificare entità da lui stesso definite
(variabili, matrici, unità di programma, aree di memoria riservate, etc.).
Parole chiave
Nel linguaggio FORTRAN «parola chiave» è sinonimo di «codice operativo».
Una parola chiave è infatti una successione di caratteri alfanumerici a cui il com
pilatore attribuisce un particolare significato (ad esempio «WRITE» significa
«scrivi», «READ» significa «leggi» e così via) .
Si noti che non esistono in F77 nomi riservati nel senso che la stessa successio
ne di caratteri può essere usata, ovviamente con significato diverso, sia come nome
simbolico che come parola chiave: il compilatore è in grado di determinare il signi-,ficato corretto in base al contesto in cui la successione di caratteri compare.e
4.4. Frasi eseguibili e non eseguibili
Le frasi FORTRAN si classificano come 1!.~~s{!glii~ili e frasi non eseguibili(cfr. appendice A3): le prime specificano delle azioni che dovranno essere compiute
in fase di esecuzione e vengono tradotte in una o più istruzioni del linguaggio mac
china; le seconde non descrivono azioni ma forniscono informazioni al compila
tore specificando, ad esempio, particolari caratteristiche o proprietà dei nomi
simbolici usati (frasi dichiarative o di specificazione) oppure classificando le unità
di programma. J-e fr_~Lnol1_~~ui~illE.9n vengono tradotte in istruzioni del lin-. guaggio macchina.
.b~ frasi che compongono ciascuna unità di programma devono rispet!a..!~.':!~
preciso ordine che impone, ad esempio, che le dichiarative Er~~~dano le eseglJi~
bili (cfr. appendice f\3).
4.5. Etichette
Ad una frase FORTRAN può essere assegnata una etichetta (/abel) in modo chealtre frasi della stessa unità di programma possano farvi riferimento.
Un'etichetta è costituita da una successione di n cifre decimali, l ~ n ~ S, di
cui almeno una diversa da zero. Se n < 5 vengono ignorati i caratteri blank eventualmente presenti tra una cifra e l'altra, Inoltre le cifre zero eventualmente pre-
so
senti nelle prime posizioni dell'etichetta non sono significative ai fini della sua di
stinzione da altre etichette. Così, ad esempio, O1234, l v 234, '171234, 1234'17 in
dicano la stessa etichetta. E' ovvio che in una stessa unità di programma non pos
sono esserci due o più frasi con la stessa etichetta. Non è invece considerata un
errore la presenza di etichette superflue ossia etichette alle quali non viene mai
fatto riferimento nel corso della stessa unità di programma; alcuni compilatori
segnalano però come situazione «anomala» la presenza di etichette superflue.
Osserviamo che tutte le frasi FORTRAN possono essere accompagnate da una eti
chetta ma è possibile far riferimento diretto a11e sole frasi eseguibili ed alla fraseFORMAT (cfr. cap. 13).
4.6. Il formato delle linee
SI
• non è possibile finire una frase FORTRAN ed iniziame un'altra sulla stessa
linea;• il testo della frase va scritto nelle colonne che vanno dalla 7-ma alla 72-ma Iv
\1 comprese;• una frase può essere formata da più linee (fino ad un massimo di venti). La
prima linea è detta linea iniziale e le altre sono dette linee di continuazione;
una linea di contin~azione è caratterizzata dalla presenza di un carattere diverso (j'!
vi' da blank o zero a colonna 6; -
• l'eventuale etichetta di una frase deve essere scritta nelle colonne da I a 5 della
linea iniziale.
:'
t,I
:.1
~
Un programma FORTRAN si presenta fisicamente come una successione di
linee che vengono scritte in modo sequenziale su opportuni supporti.
Ciascuna linea è costituita da una successione di 72 caratteri dell'alfabeto--- - ----- .-
FORTRAN e la posizione di ciascun carattere in una linea è detta _c_ol~nn!1~
I più comuni supporti su cUI vengono scritte le linee di un programma permet
tono di comporre linee con un numero di caratteri superiore a 72. Gli eventuali
caratteri presenti in una linea a partire da11a colonna 73 in poi sono però ignorati
dal compilatore FORTRAN ai fini della creazione del programma oggetto; essi
possono però essere riprodotti in una lista ovvero in una copia del programma
sorgente. La presenza di caratteri successivi al 72-mo non è quindi «sentita»
in alcun modo dal compilatore FORTRAN il quale, ignorandola completamente,
non la segnala in alcun modo al programmatore; questo può essere fonte di errori
in compilazione e/o in esecuzione non sempre facilmente rintracciabili.
Una linea di un programma è considerata linea di commento e viene del tutto
ignorata dal compilatore quando è interamente costituita da caratteri blank,
oppure quando ha uno dei due caratteri C o * a colonna 1.
Una linea di commento può contenere nelle colonne successive alla primaqualunque carattere, anche non appartenente all'alfabeto FORTRAN, che sia
stampabile, ovvero riproducibile su un supporto esterno quale ad esempio unvideo o un foglio di carta.
Una linea di commento può stare in qualunque punto dell'unità di programma.
Le linee di commento vengono riprodotte nella lista del programma e servono
quindi per facilitare la lettura e la comprensione del programma stesso.
(In F66 una linea è considerata di commento soltanto se ha il carattere C a ~
colonna l. ,
Una linea che non sia linea di commento deve essere composta tenendo pre-senti le seguenti regole:
c o 1t (o tr i'~' /', O
~4' l ~ 4 r ,.,.
~7LL' 'ClOU/'c/',
{OI"l"L"t'Ot1I~ (7unl
12__________ -.1.+--- . _
5Costanti e variabili:elementi fondamentali di ogni istruzione
Ogni istruzione FORTRAN che elabora un'informazione deve far riferimento
alla locazione di memoria nella quale è contenuta l'informazione stessa. Tale informazione può o meno variare durante l'esecuzione del programma: nel primocaso la locazione di memoria deve essere identificata da un nome simbolico
mentre nel sec<.>ndo~ssa !,uò essere identificata da una costante.
5.1. Le costanti ed il loro tipo
In F77 sono previste costanti di tipo diverso: intero, reale. doppia precisione.complesso. logico e carattere. Ogni tipo corrisponde a modalità diverse di rappresentazione in memoria del valore identificato dalla costante. La forma di una costante ne specifica il tipo ed il valore.
Costanti intere
Si definisce costante intera una stringa di cifre decimali eventualmente preceduta dal segno + o -. Formalmente una costante intera può essere rappresentatada
~~dove s indica il segno ed n indica una stringa di cifre decimali. Se il segno s manca,la costante si intende essere positiva.
Esempio 5.1. Sono costanti intere le seguenti:
-2 + 37 - 578 1957 - 15878 -I o 3
in quanto nella stringa n compaiono simboli non consentiti (il punto decimale ela virgola).
l b
mentre non lo sono:
- 2.0 1.957 + 0.1 - 15,73
F
54 55
Il valore rappresentato da una costante intera è memorizzato in una unità di
memoria numerica secondo le modalità viste per la rappresentazione dei numeri
interi.
ciascuna delle quali rappresenta il valore 1O~ 3;
- 4.857E + 03 -.4857E + 04 - 485. 7E I
ciascuna delle Quali rappresenta il valore -4857.
- 4857.EO
Costanti reali
Esempio 5.2. Sono costanti reali nella forma senza esponente le seguenti:
Le costanti reali rappresentano valori che vengono memorizzati in virgola
mobile normalizzata all'interno di una unità di memoria numerica secondo lemodalità viste per la rappresentazione dei numeri reali. Una costante reale può
essere scritta in due modi: senza esponente e con esponente.
Nella forma senza esponente, caratterizzata dalla presenza del punto decimale,
la costante è scritta come
/s n. 011dove s indica il segno mentre n ed m sono stringhe di cifre decimali. Il segno può
mancare ed in questo caso la costante è intesa come positiva. Anche una delle
due stringe n ed m può esser vuota ed in questo caso la stringa mancante è consi
derata uguale a zero.
+ 0.7 + 23.5 - 0.001 + 0.0 .05 - 1. O.
In F77 è prevista una forma esponenziale senza il punto decimale non consen
tita in F66. Così sono valide le costanti 1E - 2 per rappresentare 0.0 I oppure
_ 503E - 2 per rappresentare - 5.03.
Le costanti reali sono spesso dette anche costanti reali in precisione semplice
per distinguerle esplicitamente dalle costanti reali in doppia precisione.
Costanti in doppia precisione
Una costante reale in doppia precisione rappresenta un valore che viene memo
rizzato in virgola mobile normalizzata in una cella costituita da due unità di me
moria numeriche consecutive.
Le costanti di questo tipo vengono scritte soltanto nella forma esponenziale
con la lettera TI che sostituisce la Eusata per le costanti reali in precisione sempli
ce. Pertanto una costante in doppia precisione è della forma:
l~-~~mDse Idove s, n, m ed e hanno lo stesso significato visto per le costanti reali.
Nella forma con esponente, caratterizzata dalla presenza della lettera E, la co
stante è scritta come: Esempio 5.4. Alcuni esempi di costanti in doppia precisione sono i seguenti:
+ 3.875D + 00 387.5D - 02 3875.D - 3 .3875Dl
ciascuna delle quali rappresenta il valore 3.875; le costanti
Isn.mEse\
dove s indica un segno, mentre n, m ed e sono stringhe di cifre decimali. Il signifi
cato della forma esponenziale è il seguente: + 1000.D + 00 + I.D + 03 I.D3 1 D3
s n . m x l O'" rappresentano invece il valore 1000.
Esempio 5.3. Sono costanti reali nella forma con esponente le seguenti:
ovvero la costante intera e che segue con il suo segno la lettera E ha il signifi
cato di esponente rispetto alla base dieci e il suo valore è legato alle limitazioni
di overtlow e di undertlow per i numeri reali. Il segno s può mancare ed in questo
caso si suppone che esso sia +; una delle due stringhe n ed m può mancare ed è
considerata uguale a zero.
ciascuna delle quali rappresenta Il valore - 5.03;
Anche per questo tipo di costante va osservato che la versione senza il puntodecimale è valida soltanto in F77.
indica il numero complesso 1.5 + 7.3i
indica il numero complesso 1 - 7i.
(1.5, 7.3)
(1.,-.7EI)
Costanti di tipo complesso
Le costanti di tipo complesso sono usate per rappresentare numeri complessi
e vengono scritte come coppie di costanti reali separate da una virgola e chiuse tra
parentesi:~~':TI~_c()~~nte rappresenta la parte reale del numero complessomentre la seconda rappresenta la parte immaginaria. Così, per esempio:
- 503.E - 2
+ O.OOIE + 00
- 50.3E - 1
.IE - 2+ LE - 3
- 0.503E + 01- 5.03E + 00
+ I.E - 03
56
Le costanti di tipo complesso sono memorizzate in celle costituite da due uni
tà di memoria numeriche consecutive.
Costanti di tipo logico
Siccome i valori logici possibili sono soltanto due si hanno due sole costanti
logiche:
.TRUE. e .FALSE.
ossia «vero» e «falso». I punti che accompagnano le stringhe TR UE (FALSE)
fanno parte integrante della costante e non possono essere omessi.
Una costante di tipo logico è memorizzata in una unità di memoria numerica.
Costanti di tipo carattere
Questo tipo di costanti è previsto soltanto in F77; per la loro definizione e uti
lizzazione si veda il cap. 12.
5.2. Le variabili ed il loro tipo
Una variabile è una cella il cui contenuto (valore) può variare durante l'esecu
zione del programma ed il nome simbolico che la identifica, detto nume di varia
bile. la distingue da ogni altra cella della stessa unità di programma. Il nome
simbolico di una variabile deve soddisfare le regole viste nel § 4.3. Sono quindi
corretti i nomi:
A Al NOME X3Y COST SOMMA DIFFE N23
mentre non lo sono:
lA Al. NOME! X3 + Y COjST DIFFERENZA.
Le variabili FORTRAN possono essere di tipo intero, reale, doppia precisione, complesso, logico e carattere. Ad ognuno di questi tipi corrisponde una diversa
rappresentazione in memoria del valore della variabile ed una diversa lunghezza
delle celle destinata a contenerlo. Ogni variabile intera, reale o logica occupa infat
ti una unità di memoria numerica mentre ogni variabile di tipo doppia precisione
o complesso occupa due unità di memoria numeriche. Le variabili di tipo carat
tere sono memorizzate secondo modalità diverse che verranno esposte nel cap.
12.
La lettera iniziale di un nome di variabile può essere usata per distinguere
le variabili di tipo intero da quelle di tipo reale. Le variabili reali sono infatti
caratterizzate da nomi che iniziano con una qualunque delle lettere dalla A alla
H o dalla O alla Z; le variabili intere sono invece contraddistinte da nomi che ini
ziano con una dellelettere I, J, K, L, M, N.
57
Esempio 5.5. Sono nomi di variabili intere i seguenti:
NOME LPI 13 KST AR IND JSOMMA
mentre sono nomi di variabili reali:
OME AMAX SOMMA A I DIFFE STAR.
Se il tipo di una variabile non è intero o reale. esso deve essere esplicitamente
sp~cific!!!Q. Per specificare esplicitamentejltipo di una variabile si usano frasi che
dire~~ di specificazion!.. (dichiarative) di tipu che hanno la 'io~ma
tipo lista
dove:
• tipo sta ad indicare uno dei seguen ti dichiaratori:
INTEGER, REAL, DOUBLE PRECISION. COMPLEX, LOGICAL,
CHARACTER;
• lista indica una successione di nomi di variabile separati da virgole.
L'effetto di una frase dichiarativa di tipo la cui lista sia costituita da nomi di
variabile è quello di comunicare al compilatore che tali variabili sono da consi
derarsi, nella unit~~i pro~ramma in cui compare la frase dichiarativa, del tipospecificato dal dichiaratore. . ..
Esempio 5.6. La frase
DOUBLE PRECISION RADIX. MAX
serve a specificare che le variabili RADIX e MAX devono essere trattate come va
riabili doppia precisione e quindi il loro valore verrà memorizzato in celle di lun
ghezza doppia rispetto a quelle riservate alla memorizzazione di variabili reali.
Ulteriori utilizzazioni delle frasi dichiarative di tipo saranno analizzate nel corso
d.el .testo. Jn ogni caso si deve tener presente che le liste che compaiono in due.Ira,SI dichiarative non possono avere elementi comuni.
Ogni unità di programma può contenere più istruzioni di specificazione di tipo
~a va sempre ricordato che .!!!!!~ le [rasi dichiarative devono essere poste primadi qualunque frase eseguibile (cfr. appendicie A3).
Anche se la lettera iniziale del nome può essere usata per distinguere le varia
bili reali da quelle intere, può essere comodo usare una dichiarazione esplicita ditipo anche per queste variabili.
58
Esempio 5. 7. Le dichiarazioni
REAL MEDIA, MINIMO
INTEGER PESO
permettono di utilizzare le variabili MEDIA e MINIMO come reali e la variabile
PESO come intera evitando l'uso di nomi «meno comodi» quali ad esempio
AMEDlA, XMINIM, KPESO.
Si osservi che è abbastanza diffusa l'abitudine di dichiarare il tipo di tutte le
variabili di una unità di programma comprese quelle intere e reali e che alcuni
compilatori possono essere utilizzati in modo da inviare un messaggio di avverti
mento, se non addirittura di errore, nel caso in cui venga utilizzata una variabile
il cui tipo non sia stato esplicitamente dichiarato. Questa scelta permette di con
trollare eventuali «errori di battitura» dei nomi di variabile e semplifica le opera
zioni che devono essere fatte quando si vuoI avere, per esempio, la versione in
doppia precisione di un programma già scritto in semplice.
5.3. L'istruzione IMPLICIT
Le variabili il cui nome non compare in nessuna frase di specificazione di tipo
si dicono di tipo implicito: la lettera iniziale del loro nome determina il loro
tipo.Per fissare il legame tra il tipo di una variabile e la lettera iniziale del suo nome
si usa l'istruzione IMPLICIT che non è prevista in F66. La forma di questa istru
zione è la seguente:
IMPLICIT tipo I (elenco l), tipo 2 (elenco 2), ...
dove:
• tipo l, tipo 2, etc. sono dichiaratori di tipo (esempio REAL, LOGICAL);
• elenco I, elenco 2, etc. sono liste costituite da una o più lettere dell'alfabeto
inglese ciascuna delle quali è separata dalla successiva mediante una virgola. Un
elenco di lettere consecutive alfabeticamente ordinate può essere indicato median
te la sua prima ed ultima lettera separata da un segno meno.
L'effetto dell'istruzione IMPLICIT è quello di specificare, mediante i dichiara
tori, il tipo delle variabili i cui nomi simbolici iniziano con una lettera che compare nella specificazione.
L'istruzione IMPLICIT ha effetto soltanto nell'unità di programma che la contiene.
Esempio 5.8. L'istruzione
IMPLICIT REAL (I, L-N), INTEGER (A-C)
r59
fa sì che tutte le variabili di tipo implicito i cui nomi iniziano con I, L, M, N
sono di tipo reale mentre quelle i cui nomi iniziano per A, B, C sono di tipo
intero.
L'utilità della istruzione IMPLICIT è evidente quando. per esempio. si vuoI
modificare da reale semplice a reale doppia precisione il tipo di tutte le variabili
di una unità di programma; per far questo basterà utilizzare il comando
IMPLICIT DOUBLE PRECISION (A-H, O-Z).
Per utilizzare correttamente l'istruzione IMPLICIT si deve anche ricordare che
essa deve precedere qualsiasi altra istruzione dichiarativa di tipo e che una dichia
rativa esplicita di tipo prevale sull'istruzione IMPLICIT.
Esempio 5. 9. La successione di istruzioni:IMPLICIT DOUBLE PRECISION (A-C)
REAL BETA, ALFA
INTEGER CPI
ha l'effetto seguente: tutte le variabili i cui nomi iniziano con le lettere A, B, C
sono di tipo doppia precisione ad eccezione delle variabili BETA ed ALFA che
sono di tipo reale e della variabile CPI che è di tipo intero.
Nel testo, quando non sia esplicitamente indicato, si suppone che il tipo dellevariabili sia implictamente definito dal loro nome.
Inoltre verrà usata la notazione
nome simbolico: valore
per indicare che la variabile, il cui nome simbolico compare alla sinistra dei due
punti, ha il valore specificato alla destra dei due punti; così, ad esempio, I : 5 significa che la variabile di nome I contiene il valore 5.
6Le espressioni
Una espressione FORTRAN è una qualunque combinazione di operandi otte
nuta tramite operatori e parentesi tonde; l'esecuzione delle operazioni indicatedagli operatori dà luogo ad un risultato che viene detto l'a/ore de/l 'espressione.
Si osservi che anche un SlOgOIO operando costituisce una espressione FORTRAN.
Le espressioni FORTRAN si suddividono in aritmetiche, reiazionali, logiche e
carattère.Queste ultime, non previste in F66, saranno trattate nel cap. 12.
6.1. Espressioni aritmetiche
Le espressioni aritmetiche sono utilizzate per ottenere come risultato un valorenumerico. Esse sono costituite da operandi di tipo numerico, quali ad esempio
variabili e costanti di tipo intero, reale, doppia precisione o complesso, e da ope
ratori aritmetici. Gli operatori aritmetici sono i seguenti:
Operatore
+
*
**
Operazione aritmetica
addizionesottrazionemoltiplicazione
divisioneelevamento a potenza
Osserviamo che in un'espressione aritmetica non sono permessi due operatori
consecutivi, e che l'operazione di moltiplicazione va sempre indicata con il simbo
lo *. Così, per esempio, sono valide le seguenti espressioni:
1+3 .. 2
mentre sono esempi di espressioni non valide i seguenti:
x * - Y A + - B 5.5 * - l x ** - Y
( 62 63
e, nell'ambito dello stesso livello di priorità, il calcolo viene eseguito da sinistra
verso destra.
Esempio 6.1. L'espressione 1.0 + 3.0 * 2.0 viene valutata eseguendo prima la
moltiplicazione, che dà come risultato 6.0, e dopo l'addizione fra 1.0 e 6.0; il
risultato finale è quindi 7.0 (cfr. fig. 6.1).
3.0
ti10.0 2.
Y5~/2
Calcolando da sinistra verso destra le addizioni e sottrazioni, il risultato finale è
18.0(cfr. fig. 6.2).
priorità alta
priorità media
priorità bassa
*** e I+e-
3.0 2.0
V1~~1
Valutazione delle espressioni aritmetiche
La valutazione di un'espressione aritmetica avviene usando i contenuti dellecelle di memoria indicate dagli operandi nel modo indicato dagli operatori; per
esempio l'espressione X + Y viene valutata sommando il contenuto della cella
di nome X con quello della cella di nome Y. Se in un'espressione compaiono di
versi operatori la sua valutazione avviene tenendo presenti le seguenti priorità:
Figura 6.1. Valutazione dell'espressione 1.0 + 3.0 * 2.0. Figura 6.2. Valutazione dell'espressione 5.0 + 10.0/2.0 + 3.0 .. 2 - 1.0.
Esempio 6.2. L'espressione
5.0 + 10.012.0 + 3.0 ** 2 - 1.0
viene valutata eseguendo innanzitutto l'elevamento a potenza che dà come ri
sultato .lII = 9.0. L'espressione pertanto diventa:
5.0 + 10.0/2.0 + 9.0 - 1.0.
Esempio 6.3. L'espressione A + B/C ** D viene valutata eseguendo prima l'elevamento a potenza C ** D; indicato con .0l
Iil risultato di questa operazione,
l'espressione diventa A + B/9f l' viene quindi eseguita la divisione B/9f I ottenendo un risultato 9f
2; il risultato finale '~3 è ottenuto eseguendo l'operazione
A + .!jI2 (cfr. fig. 6.3).
Viene quindi eseguita la divisione e si ottiene:
5.0 + 5.0 + 9.0 - 1.0.
i~
,-Jf4 ~ A + ;7i 3
Figura 6.4. Valutazione dell'espressione A + H/C ** D * E-F.
Jf 5
6S
fJtl +-C" D
A + 913 - F
914 - F
C D
VBy~1
V~l
fJt3 fJt 3 +- A + ,rJt2Figura 6.3. Valutazione dell'espressione A + H/C •• D.
fJl3 +- fJl2 * E ~
914 +-A + fJl3~
fJl +- 9t -F5 4
Esempio 6.4. La valutazione dell'espressione
A + B/C ** D • E - F
può essere così schematizzata (cfr. fig. 6.4):
64
911 +- C ** D ~ A + B/ ,0l l • E - F
912 +- B/91 l ~ A + fJt2
• E - F
Uso delle parentesi
L'utilizzazione delle parentesi tonde permette di modificare la priorità di ese
cuzione delle operazioni aritmetiche in quanto, al momento della valutazione di
una espressione, vengono eseguite per prime le operazioni racchiuse tra parentesi,
Quando una coppia di parentesi è racchiusa in un'altra, l'espressione contenuta
nella coppia più interna viene calcolata per prima.
Esempio 6.5. L'espressione (X + Y) * W viene valutata calcolando prima
,7f l +- X + Y, e poi ,'79 2 +- ,?fl * W; essa corrisponde all'espressione algebrica
(x + y) w. L'espressione X + Y * W, corrispondente invece a x + y w, viene cal
colata valutando prima ,?fl +- Y * W e dopo .?f2 +- X + ,7f l'
a + bEsempio 6.6. L'espressione algebrica --- deve essere scritta in FORTRAN
ccome (A + B)/C, in quanto l'espressione A + B/C equivale all'espressione algebri
bca a + e non a quella data (cfr. fig. 6.5).
c
aEsempio 6.7 L'espressione algebrica - è correttamente trascritta in FORTRAN
bca
come A/(B * C), mentre A/B * C corrisponde alla espressione - c (cfr. fig. 6.6).b
66 67
a+b bFigura 6.7. Calcolo di -- e a + - + d.
c+d c
Elevamento a potenza
In F77 due successivi. elevamenti a~ potenza sono valutati iniziando da quello---- ... -----.-~. -.---. . ~ c
di de;tra: A ** B ** C equivale a a(b). In F66 non è invece consentito l'uso di
du~ elevamenti a pote~~~ ~ucces-siVl senon utilizzando le parentesi; perciò, in F66,
l'operazione a(bc) deve essere trascritta come A ** (B ** C)._~~e..r:e~s!o.!1_e~!g~
brica (ab)~anUnvec~ tradottasiainFéé chejn,F77 come (A ** B) ** C. Così,
per esempio, se i valori contenuti nelle celle di nome A, B, C sono:
be a+ -.
cc
a+bFigura 6.5. Calcolo di
91,--- A/.r~l
B C
VAtp~1
II,\!
I:
a aFigura 6.6. Calcolo di - e b c.
bc allora
A: 2. B : 2. C: 3.
fig. 6.7).
bcome (A + B)/(C + D), mentre A + B/C + D corrisponde ad a + -+ d (cfr.
c
Esempio 6.8. L'espressione algebricaa + b
c+ddeve essere scritta in FORTRAN
(A ** B) ** C
A ** (B ** C)
A ** B ** C
viene eseguita valutando 2. 2. = 4. e poi 4.3. = 64.;
viene eseguita valutando 2. 3. = 8. e poi 2. 8 = 256.;
non viene eseguita in F66 in quanto considerata
ambigua, mentre in F77 essa equivale alla prece
dente.
Le parentesi possono anche essere usate per separare due simboli di operatori
aritmetici; così per esempio. dovendo trascrivere l'esnressione algebrica a- b. si
deve scnvere A ** (- B) e J espressione algebrica - ba può essere corretta
mente scritta come - B * A oppure come A * (- B).
Osserviamo che in F66 una grandezza numerica di qualunque tipo può essere
elevata ad esponente intero, ma soltanto le grandezze reali possono essere elevate
ad esponente reale. In F77, invece, sono permessetuttelecombinazioni di tipo
tra la base e l'esponente.Tatta eccezioneper quelle checoinvolgono i tipi doppia
precisione e complesso. Le combinazioni consentite in F66 e F77 sono riassunte
68 69
in fig.6.1) e 6.9 rispettivamente, dove I, R, Dp, C indicano i tipi intero, reale,
doppia precisione, complesso.
Dalle figure risulta evidente che, mentre un'espressione come I ** J oppure
AK ** 5 è permessa in qualunque versione del FORTRAN, le espressioni 3 ** 0.5
oppure I ** R non sono valide in F66.
~ Va osservato che in FORTRAN la divisione fra interi dà come risultato la parte IlA
1intera d~!d~~lt~t~che si otterrebbe eseguendo l'operazione in aritmetica reale: trCosì il valore della espressione FORTRAN 1/2 è Omentre 1./2. dà come risul
tato 0.5. Analogamente:
Nella valutazione delle espressioni intere contenenti una o più operazioni di
divisione è quindi molto importante l'ordine in cui le operazioni vengono effet4
tuate. Si consideri, ad esempio, l'espressione algebrica - . 3: essa è trascritta cor3
rettamente nell'espressione FORTRAN intera 4 * 3/3 il cui valore è 4, ma non
nell'espressione intera 4/3 * 3 il cui valore è 3.
k - n(K - N)/M * J.
vale zero qualunque siano i valori di l e J;
vale - l;
vale N se e soltanto se N è pari;
vale N qualunque sia N;
vale zero se M è minore di N in valore assoluto.
1/2 * (l +J)4/(5-8)
N/2 * 2N * 2/2N/M * M
J * (K - N)/M e
Esempio 6.9. Le seguenti espressioni intere
~ l R Dp Cbase
l sì sì sì sì
R sì sì sì sì
Dp sì sì sì no
C sì sì no sì
Figura 6.9. Elevamento a potenza in F77.Figura 6.8. Elevamento a potenza in F66.
~ l R Dp Cbase
l sì no no no
R sì sì no no
Dp sì no sì no
C sì no no no
Il r
Ossen'azione 1. Mentre l'operazione di elevamento a potenza con esponente in
tero viene di solito eseguita tramite moltiplicazioni ripetute, quella con esponente
reale richiede il passaggio al logaritmo, e quindi un tempo di calcolo maggiore.
Dovendo allora calcolare a3 , conviene usare l'espressione A ** 3 anziché A ** 3.0.
Osservazione 2. La definizione matematica di elevamento a potenza nel campo
reale impone alcune restrizioni: non può essere elevata ad esponente negativo o
nullo un'espressione il cui valore sia zero, e non può essere elevata ad esponente Ireale un' espressione il cui valore sia negativo. .Il \
_____ ~~ j'J
Uso dell'aritmetica intera e reale
Se un operatore aritmetico opera su grandezze dello stesso tipo il risultato di
un'operazione è un valore il cui tipo coincide con quello degli operandi; esso vie
ne determinato eseguendo l'operazione in aritmetica intera, reale, doppia pre
cisione o complessa a seconda del tipo degli operandi. Così, ad esempio, 3 + 5
dà come risultato il numero intero g, mentre 3. + 5. dà come risultato il valore
reale 8. che viene memorizzato in virgola mobile normalizzata. Ancora, mentre
l'espressione 30875 + 7874, facendo uso dell'aritmetica intera, può dar luogo
su alcuni elaboratori a fenomeni di overf1ow, l'espressione 30875. + 7874. uti
lizza l'aritmetica dei reali e il risultato, ovvero il numero 38749., è rappresentato
in memoria come reale.
pur trascrivendo in modo corretto le espressioni algebriche equivalenti jk-n m
e -- j, possono dare risultati numericamente diversi. Per esempio, se i conm
tenuti delle vanabili sono
K:5 N:3 M:4 J:8
la prima espressione vale 4 (cfr. fig. 6.10) e la seconda vale zero (cfr. hg.6.11).
.~3 9f] +-.0f 2/4
Figura 6.10. Valutazione di ~ * (S - 3)/4.
j"
70
f
71
Operazioni fra numeri complessi
Le operazioni aritmetiche tra operandi di tipo complesso danno come risultato
un numero complesso. In fig. 6.12 si ricordano le definizioni matematiche delle
operazioni elementari fra complessi intendendo zi = u 1 + i v1 e z2 = u2 + i v2·
Osserviamo che anche nel caso di espressioni non intere può essere fondamenta
le l'ordine in cui le operazioni vengono effettuate. Infatti il risultato di un'operazione fra due numeri reali rappresentabili in macchina può non essere un numero
rappresentabile in macchina, e deve quindi essere approssimato con la sua rappre
sentazione floating point (cfr. cap. 3). In questa gerarchia il tipo doppia precisione e complesso sono allo stesso li
vello in quanto essi non possono coesistere in una stessa espressione.
La regola generale che comanda l'esecuzione delle operazioni aritmetiche resta
ancora valida; pertanto se il tipo di due operandi non è lo stesso, quello più debole
~iene automaticamente modificato in quello più forte mediante un'operazione,
detta di conversione, che permette il passaggio da una rappresentazione intem-a .
i ad un'altra. Anche se la possibilità di combinare in un'espressione operandi di
tipo diverso è molto comoda, va osservato che essa dà luogo in generale ad un'ela- l,
borazione più lenta, in quanto l'operazione di conversione «costa» un certo tem
po macchina.
Operazione RisultatoParte reale Parte immaginaria
I) Doppia precisione, complesso
2) Reale
3) Intero
più forte
1più debole
U1 +u2 v1
+ v2
u1-U2 vI - ":
u1u 2 - v
1v2 U
1V2+V1U2
U1U2+V1V2 U2v
1- v2U
1
Iz21 IZ21
Vu2 + v2 zero2 2
Esempio 6.11. Si consideri l'espressione 1.1 + 2; in essa sono presenti due gran
dezze di tipo diverso: 1.1 che è reale e 2 che è intera. Siccome l'operazione può
essere eseguita soltanto fra operandi dello stesso tipo, il risultato viene calcolato
in due fasi:
• la costante 2 viene convertita dal tipo intero a quello reale (più forte);
• viene eseguita l'operazione di addizione facendo uso dell'aritmetica reale e siottiene il valore 2.1.
Figura 6.12. Operazioni elementari fra numeri complessi.
Esempio 6.10. Supponiamo che la variabile complessa li contenga il valore
5 + 3i e l2 contenga 2.5 - 1.1 i.
L'espressione l l + l2 dà come risultato un valore complesso la cui parte
reale è data da 5. + 2.5 = 7.5 e quella immaginaria da 3. - LI = 1.9.L'espressione l I + l2 - (8.7, LE - I) dà ancora un valore com plesso la
cui parte reale è uguale a 7.5 - 8.7 = - 1.2 e quella immaginaria è uguale a
1.9 - LE - I = 1.8.
Espressioni aritmetiche miste
Le operazioni aritmetiche di addizione, sottrazione, moltiplicazione e divisio
ne possono essere eseguite soltanto tra operandi dello stesso tipo. E' però possi
bile utilizzare in una stessa espressione operandi di tipo diverso dando luogo a
quelle che vengono dette espressioni miste. In queste espressioni le operazioni
vengono eseguite tenendo presente la seguente gerarchia fra i tipi degli operandi:
6Esempio 6.12. Consideriamo l'espressione algebrica "5 a. , ~( fClll 't' ,
Essa può essere trascritta nell'espressione mista 615 * A che, pur essendo
sintatticamente corretta, dà luogo ad un risultato sbagliato: la sua valutazione
infatti prevede innazitutto l'esecuzione della divisione fra interi 6/5 che dà come
risultato il numero intero I; l'operazione successiva I * A è di tipo misto e l'ope
rando intero l viene convertito nel suo equivalente reale prima di essere molti
plicato per il contenuto della variabile A. Il risultato dell'espressione FORTRAN6
6/5 * A è quindi A. L'espressione - a può invece essere correttamente tradotta5
come 6 * A/5 oppure 6./5 * A (cfr. fig. 6.13).
Uso delle funzioni intrinseche
Oltre alle operazioni aritmetiche di addizione, sottrazione, moltiplicazione,
divisione ed elevamento a potenza, sono spesso necessarie operazioni più com
pIesse quali, ad esempio, il calcolo dei logaritmi, di funzioni trigonometriche,
ecc .. Tali operazioni vengono eseguite in FORTRAN usando opportune procedu
re, dette funzioni intrinseche, ciascuna delle quali è indicata da un nome. Così,
per esempio, la funzione esponenziale è indicata da EXP, la radice quadrata da
72 73
Figura 6.13. Valutazioni di espressioni miste relative all'esempio 6.12.
• si converte 6 da intero a reale: 6.0
• si calcola 6.0 * A - Risultato reale: ;jfl +- 6.0 * A
si converte 5 da intero a reale: 5.0
• si calcola 3f1/ 5 .0 - Risultato reale: ;'f,f +- :'Jf1/ 5 .
OperazioneNome della Numero di Tipo degli Tipodc:l
funzione argomenti argoment i risultato
{'m l l, R, Dp.C InteroREAL l I, R, Dp,C Reale
Conversione DBLE l I, R, Dp,C Doppia precisioneCMPLX 102 I, R, Dp,C Complesso
Modulo ABS C RealeValore assoluto ABS I, R, Dp Il tipo delRadice quadrata SQRT R, Dp, C risultato coincideEsponenziale EXP R, Dp,C con quello degliLogaritmo naturale LOG R, Dp, C argomenti che,Seno SIN R,Dp,C nel caso siano piùCoseno COS R,Dp,C di uno,<k"l1l10Tangente TAN R,Dp essere tu IliMassimo fra più valori MAX 2 o più I, R,Dp dclIostessoMinimo fra più valori MIN 2 o più I, R,Dp tipo
SQRT (678.36)EXP(Y)MlN (J,. 3 + N, 8)A + SIN (0.5 * TETA)0.5 * (H + A/SQRT(X»B/(ABS (X Y) * EPS)EXP (ABS (H/2»SQRT (13 * C + SQRT(A))
Figura 6.14. Alcune funzioni intrinseche in F77.
SQRT, il valore assoluto da ABS. In fig. 6.14 sono riportate alcune delle principali
funzioni intrinseche disponibili in F77 (per un elenco completo cfr. cap. 14).
Ciascuna funzione opera su uno o più dati, detti argomenti, e fornisce un
unico risultato che può essere utilizzato scrivendo il nome della funzione seguito
da una lista di argomenti racchiusa fra parentesi. Nella maggior parte dei casi è
previsto un solo argomento; quando però gli argomenti sono più di uno, essi de
vono essere separati da virgole.
Per utilizzare correttamente una qualunque funzione intrinseca è fondamentale
che il numero e il tipo degli argomenti coincida con quello specificato in fig.
6.14; così, ad esempio, SQRT (2) è un'espressione sbagliata in quanto la funzione
SQRT non può essere usata con argomenti di tipo intero. 9ss~.!Yi!!!l1o che un ar
somentc di tipo sp'!gliatQ non yienecQny~rtit9 autcmaticamente ad un tipo -coj--~
retto, e che inoltre errori di questo tipo non vengono di solito segnalati e generano
quindi risultati imprevedibili.
Sono esempi di espressioni che utilizzano funzioni intrinseche i seguenti:
'1- 6 /5=1
6
!6. A
"cfgf
l
6 5
"cf31'1 AJI\ - 6./5. = l~
"cf
6./5 * A
• si converte 5 da in tero a reale: 5.0
• si calcola 6.0/5.0 - Risultato reale:
9f t +-6./5. = 1.2
• si calcola .3f1 * A - Risultato reale:
91 +- 3f1 * A = 1.2 * A.
6/5 * A
6 * A/5
• si calcola 6/5 - Risultato intero: l
• si converte l da intero a reale: 1.0
• si calcola 1.0 * A - Risultato reale gf +- l. * A
74 7S
.<al6 - 994 + ~s'
~ C. EXP (X •.'lfl-I.O)
~ C * EXP (.<al 2 - \.0)
~ C * EXP ( fJf 3)
~ C * Y9 4
~1- LOG(X)
,<al 2-X·gpl
91 3 - .rjl2 - \.0
(jf 4 - EXP(.rjl 3)
{jfs-C. fJf4·
Esempio 6.15. Valutazione di C. EXP (X • LOG(X) - 1.0)
~6 - 2.• A
:19 7 - ~S/fJf6'
Esempio 6.16. Valutazione di SQRT(X + SQRT ( 1.0 + X» + X * Y
8l 1- 1.0 + X ~ SQRT(X+SQRT({jfI»+X*Y
9P 2 - SQRT ('~I) ~ SQRT (X + fJf 2) + X * Y
(jf3- X + 91 2 ~ SQRT(.<al3) + X * Y
Come si vede da questi esempi, una qualunque espressione può essere usata
come argomento di una funzione intrinseca; il tipo dell'espressione deve coinci
dere con uno di quelli specificati dal FORTRAN per l'argomento corrispondente.
L'espressione usata come argomento di una funzione intrinseca può ridursi ad
una costante o ad una variabile come nei primi due esempi, oppure può coin
volgere operazioni aritmetiche e/o riferimenti ad altre funzioni intrinseche. E'
inoltre premesso utilizzare in un argomento di una funzione intrinseca la fun
zione stessa (cfr. l'ultimo esempio).Molte funzioni intrinseche in F77 possono avere argomenti di tipo diverso:
in generale il risultato è dello stesso tipo degli argomenti che, se sono più di uno,
devono essere tutti dello stesso tipo. Per esempio, se X è una variabile in doppia
precisione e K una variabile intera, i loro valori assoluti possono essere determinati
rispettivamente da ABS(X) e ABS(K) e. mentre il risultato di ABS(X) è un valorein doppia precisione, quello di ABS(K) è intero; se C è una variabile complessa
il risultato di ABS(C) è un valore reale, il modulo di C.
Osserviamo che lo standard F66 prevede nomi diversi per funzioni che operano
su argomenti di tipo diverso. Così, ad esempio, il valore assoluto di un intero deve
essere calcolato mediante la funzione IABS, di un reale mediante ABS, di una
quantità in doppia precisione mediante DABS, e il modulo di un numero com
plesso mediante CABS (cfr. cap. 14 e appendice A2).Se in un'espressione aritmetica compare un riferimento ad una funzione in
trinseca, questa viene valutata prima di effettuare qualunque altra operazione
aritmetica. Da ciò segue che le espressioni che compaiono come argomenti dì uria
funzione saranno le prime ad essere valutate e, se esse utilizzano a loro volta una
funzione, questa avrà la precedenza.
Esempio 6.13. Valutazione di A + SIN (0.5 * TETA)
9P 1 - 0.5 * TETA ~ A + SIN ('~I)
.<al 2-SIN(.<al I) ~A+~2
~3-A+.<al2·
Esempio 6.14. Valutazione di SQRT (B ** 2 - 4. * A * C)/(2. * A)
~1-B**2 ~ SQRT (~I - 4. * A * C)/(2. * A)
992 - 4. * A ~ SQRT (fAI - fA2 * C)/(2. * A)
fA3 - fjf 2 * C ~ SQRT ( fjf I - fjf 3)/(2. * A)
9P 4 - fjf\ - fjf3 ~ SQRT (fA4)/(2. * A)
Si osservi che alcune funzioni intrinseche permettono di eseguire operazioni
di conversione di tipo e possono essere usate per modificare il tipo del risultato
dell'espressione che costituisce il loro argomento. Così, ad esempio, la funzione
REAL permette di convertire in reale quantità di altro tipo e la sua utilizza
zione può essere esemplificata dalle seguenti espressioni:
REAL (2 + 1)/2 REAL ( I /2) * A
L'esecuzione della prima espressione prevede la valutazione della espressione
intera 2 + I; il suo valore, 3, viene convertito in reale e successivamente diviso
per il numero intero 2. Il risultato della pnma espressione e pertanto 1.5. L'ese
cuzione della seconda espressione prevede la valutazione dell'espressione in
tera 1/2; il suo valore, zero, viene convertito in reale e successivamente molti
plicato per A. Il risultato del1a seconda espressione è pertanto zero qualunque
sia il valore della variabile A.
76
6.2. Espressioni relazionali
Un'espressione relazionale è costituita da due espressioni aritmetiche legate
da un operatore di relazione (cfr. fig. 6.15):
77
Esempio 6.20. Le espressioni:
B ** 2 .GE. 4. * A * C
B ** 2 - 4. * A * C .GE. O.
Figura 6.15. Operatori di relazione.
Esempio 6.17. X.GT. Y permette di confrontare i valori delle variabili X e Y.
L'espressione è vera se il contenuto della variabile X è maggiore di quello della
variabile Y, altrimenti è falsa.
Si può notare che, non essendo definita una relazione di ordine tra i numeri
complessi, gli unici operatori di relazione permessi con espressioni complesse
sono .EQ. e .NE.
4. * A * C - B ** 2 .LE. O.
sono tutte equivalenti e rappresentano la relazione b2 ~ 4ac.
6.3. Espressioni logiche
Le espressioni logiche sono formate dalla com binazione di valori logici median
te gli operatori logici .AND., .OR., .NOT., definiti in fig. 6.16; il valore di una
espressione logica è un valore logico.
ABS (E l - E2) .LE. TOLL
El .EQ. E2
4. * A * C .LE. B ** 2
In consegu~nza dell'uso dell'aritmetica finita, è ragionevole aspettarsi che due
espressioni teoricamente equivalenti diano in realtà risultati quasi uguali, ma non
esattamente uguali. Quindi, indicando con E I e E2 i risultati di due espressioni
non intere, l'espressione relazionale
sarà di solito falsa, anche quando matematicamente la relazione deve essere vera.Per prevenire sit~;;'i~ni-ciel-tipo o;a desc-ilitoè opp(";rt~no u~~;~~-~-t;;iTeronza~
ossia una costante positiva sufficientemente piccola per verificare una relazione
di uguaglianza approssimata: i due valori E I e E2 saranno considerati uguali se
la loro differenza è, in valore assoluto, minore o uguale della tolleranza fissataovvero se:
dove TOLL indica la tolleranza.
IVale la pena di osservare che il valore della tolleranza deve essere scelto con
estrema cura; esso dipende sia dalla precisione con cui si lavora, che dall'ordine idi grandezza di E I ed E2 e, in ogni caso, deve essere tale da evitare una defini
zione troppo approssimata di uguaglianza.
b
espressioneoperatore di relazione
aritmetica B
Notazione NotazioneSignificato
matematica FORTRAN
.EQ. uguale
*- .NE. diverso
< .LT. minore~ .LE. minore o uguale
> .GT. maggiore;;;. .GE. maggiore o uguale
espressione
aritmetica A
Esempio 6.18. ABStX - Y).LE.l.E - 6 permette 1I1 confrontare il risultato
dell'espressione ABS(X - Y) con la quantità 10- 6; l'espressione relazionale è
vera se la differenza fra i contenuti di X e Y è, in valore assoluto, minore o uguale
di l O" 6, altrimenti è falsa.
Esempio 6.}1). l + J .EQ.K + 3 permette di confrontare il risultato dell'espres
sione I + J con quello di K + 3. L'espressione relazionale è vera se i due risultati
sono uguali, altrimenti è falsa.
La valutazione di un'espressione relazionale avviene valutando separatamente
le due espressioni aritmetiche e mettendo poi a confronto i loro risultati.
Il risultato di un'espressione relazionale è un valore logico: «vero» se la relazio
ne specificata dall'operatore è verificata, «falso» altrimenti.
Le due.es2!essio~! aritmetiche che cornpaìonoIri -una" espressione relazionale
posson~~s~~.!~ ~i tipo ~iY~rso: il risultato dell'espressione di tipo più debole èconvertito, prima del confronto, nel tipo più forte. --------.
In F66 le due espressioni aritmetiche devono essere dello stesso tipo.
l
78
Dalla definizione segue che
II
LI .ANO. L2LI .OR. L2
.NOT. LI
è vero se e soltanto se entrambi i valori logici LI ed L2 sono veri;
è falso se e soltanto se entram bi i valori logici LI ed L2 sono falsi;
è vero se LI è falso, ed è falso se LI è vero.
LI L2 LI .AND. L2 LI .OR. L2 .NOT. LI
vero vero vero vero falsovero falso falso vero falsofalso vero falso vero verofalso falso falso falso vero
r79
Esempio 6.21. LEQ.O .OR. J.GT.I + 3
è valutata come (LEQ.O). OR. (J.GT.(I + 3».
Se I : 3 e J : 5 il risultato dell'espressione è il valore logico falso. mentre se
I : O e J : 5 l'espressione è vera. Notiamo che nel secondo caso è sufficiente valu
tare l'espressione relazionale LEQ.O per stabilire il risultato; in alcune realizzazio
ni del FORTRAN verrà valutata anche l'espressione J.GT.(I + 3), in altre sarà
evitato tale calcolo.
Esempio 6.22. 1** 2 .NE. N + M .ANO. 5. + B .GT. SQRT(X)
è valutata come ((I ** 2) .NE. (N + M» .ANO. «5. + B) .GT. SQRT(X»;
supponendo I : 2, N : 3, M : 5, B : 5.5, X : 4, il risultato della espressione è: vero.
Figura 6.16. Gli operatori logici .AND..OR ..NOT.
In F77 sono previsti altri due operatori logici .EQV. e .NEQV. (cfr. fig. 6.17)
tali che:
Esempio 6.23. A.LT.B .ANO ..NOT. L
è valutata come (A.LT.B) .ANO. (.NOT. L); se A : 5.1. B 7.3 e L : .TRUE.,il risultato è: falso.
I valori su CUI gli operatori logici agiscono possono essere costanti o variabili
logiche ed espressioni relazionali; un'espressione logica può quindi contenere
operatori logici, di relazione e aritmetici e nella sua valutazione vengono eseguite
prima le operazioni aritmetiche, poi quelle relazionali e infine quelle logiche,
secondo la seguente scala di priorità:
Figura 6.17. Gli operatori logici .EQV. e .NEQV.
1. + SQRT(2.)
A * 0.5 - 8.0 ** 3
3. ** (1./3) - 5. ** (1./3)(A.GT.O) .OR ..FALSE.
2+3*5
1.5 + 3.141592/2.TRUE..OR ..FALSE.
Esempio 6.24. L .ANO.'A. LE. X .OR. B .GT. 6.15
è valutata come (L. ANO. (A.LE.X» .OR. (B.GT. 6.15); supponendo L: TRUE.,
A : 15.1, X : 17.3, B : 1.0, il risultato dell'espressione è: vero.
6.4. Espressioni costanti
Un'espressione aritmetica, logica o relazionale si dice espressione costante se
non contiene nomi di variabile né riferimenti a funzioni. Inoltre, in un'espressione
aritmetica costante l'operazione di elevamento a potenza è consentita solo con
esponente intero. Sono esempi di espressioni costanti i seguenti:
mentre non lo sono i seguenti:
falsoveroverofalso
più bassa.
priorità
PiÙ['"
è vero se gli operandi hanno lo stesso valore logico;
è vero se gli operandi hanno valore opposto.( \ c!K
-----------------I-f'F'----LI .NEQV. L2
Operatore.NOT.
.ANO .
.OR.I .EQV. e .NEQV.
LI .EQV. L2
LI .NEQV. L2
LI L2 LI .EQV. L2
vero vero verovero falso falso
I falso vero falsoIl falso falso vero
I
i
Le regole suddette possono essere modificate con l'uso delle parentesi in ana
logia a quanto accade per le espressioni aritmetiche.
80
Esercizi
6.2 Calcolare il valore delle seguenti espressioni logiche:
6.1 Calcolare il valore delle seguenti espressioni aritmetiche:
81
a(b + c); a(y - b(y - c)); ab + c - a( - 3 + k):
a + bx a+b (a + b) (c + d)d2;
b - cy d a2 _ c2
c+x+y
(_X.: (a: bt5
I ( a ry-3 x2 3 + b
ab+ 3_c; ab + k c.
(36 - 2.)/5 - (4 + 2)
19/4.+3-6
- 2 ** 2/3.
2 ** 2 - 4/5
2 ** 3 - 1./2.
20/2 ** 2(20/2) ** 2 J)~.
19/(5 + 3 - 6)
19/(5 + 3 - 6.)22./(3 + 1) .~ ~
20 - 3 * 4 ((20 - 3) * 415/3*21)
15/(3 * 2)
15./(3 * 2) >,::
- l'
6.4 Calcolare il valore delle espressioni logiche
6.S Trascrivere le espressioni logiche
X + yi+ 2 + h
A+B**3
X + 3.5/Y + 4
AB/C + 2
H * S/Z + (3.1 - H * S)(37.2 * C * Z) / (A + B - C * D/3.1)
A l + X * (A2 + X * (A3 + A4 * X»
L/A ** 2 * (X/Y) ** 3(A + B * Xl/CC + D * Y) - H ** 2 + 3 - AX * (X ** 2 - Y ** 2)/(X ** 2 + Y ** 2)
- 1/(2 * X) + A ** 3/(4. * X ** 3).
X + Y ** I + 2 + H
6.8 Scrivere le espressioni matematiche corrispondenti alle seguenti espressioni:
6.9 Le seguenti espressioni FORTRAN sono sintatticamente corrette, ma non
corrispondono alle espressioni algebriche indicate. Riserivere le espressioniFORTRAN corrette.
(C .OR. D) .AND. F rt:
e LI .NEQV. L2LI .EQV. L2
C .OR. D .AND. F T eI·
1. GE. 2 ( -
(7 + I - 3) .LT. lO I(3. GT. 4) .OR. (lO - 8/2) .LT. 5
(2 ** 3 - 4./5) .LT. 10.1 .AND. 3 .GT. 1 .OR.4 .EQ. (3 + l).
per C : .TRUE., D: .FALSE., F: .TRUE.
NOT.A~T.B.AND.A.EQ.4
I Il ì '\ I
perA :4.,B :5.eperA :5.,B :4.
6.3 Calcolare il valore della seguente espressione logica:l
in altre ad esse equivalenti che facciano uso soltanto degli operatori .AND.,
.OR. e .NOT. (A + B) * CIX + Y(a + b) e
x+y
6.6 Trascrivere le espressioni logiche
.NOT. (A.GT.B .AND. A.LE.C)
.NOT. (A.LE.B .OR. A.GT.C)
in altre equivalenti in cui non si faccia uso dell'operatore .NOT.
6.7 Scrivere le espressioni FORTRAN corrispondenti alle seguenti espressioni
matematiche:
(S + Z) ** 2 + {A * B)/(C * S)
(S + Z) ** 2 + A * B/(C * S)
x * {A * X/B - C * Xl
abs(s + z)2 +
c
ab
es
axx
b - ex
82
aX • A/(B - C) • X x - - cx
b
3 a + bx3./4. R - (A + BX)/CY -r----
4 cy
haxA • B - H + A • X/0.5 • T ab---
0.5t
(ab - h) ax(A • B - H) • A • X/0.5 • T
0.5 t
a(b - h)2A • (B - H) .. 2/A + B .. 2
a + b2
A • B - H •• 2/(A + B) .. 2 (~fa+b
6.10 Usando le opportune funzioni intrinseche, scrivere le espressioni FORTRAN
corrispondenti alle seguenti espressioni matematiche
-1f 3a e.Jbii ;
-1f- e- x+ - sen x; In (a 2 + x2);
2 2 2
- l 2a ( 2 ) 1/2 Il + sen x I;Vx2 + y2 3~'
-;; sen x; In2 l - sen x
sen 3 x cos 2x 7 p; xy l- sen (nx); 6 x
2+) - - - In Ix - y I ;3 3 2 2
e v'3+k max (a, b, c)
Vr2 + (2 1ff- l f .J3 (x 2 + y2) l + min (a 2, b2, c2 _ l)- fg21f
7La frase di assegnazione
7. t. Introduzione
L'istruzione di assegnazione è tra le più importanti in FORTRAN in quanto
permette di memorizzare un valore in una particolare locazione di memoria.
La forma generale di questa frase è:
v = espressione
dove:• v è un nome simbolico di variabile;
• espressione è una espressione FORTRAN.
L'esecuzione di frasi di questo tipo avviene calcolando prima il valore del
l'espressione e memorizzando poi tale valore nella cella identificata dal nome
v. Il simbolo = ha quindi in FORTRAN un significato completamente diverso
da quello matematico: esso permette di definire il contenuto della cella di memo
ria individuata dall'identificatore v che compare alla sua sinistra attribuendogli
il valore dell'espressione scritta alla sua destra; esso è quindi equivalente al simbo
lo <- visto nel linguaggio dei diagrammi a blocchi. Mediante una frase di asse
gnazione è allora possibile indicare quali operazioni si vogliono eseguire e su
quali operandi ed in quale locazione di memoria si vuoI trasmettere e conservare
il risultato ottenuto. Tenendo presente il tipo del contenuto di una cella di me
moria è possibile distinguere tra assegnazione aritmetica, assegnazione logica ed
assegnazione tra stringhe di caratteri. Esaminiamo qui i primi due tipi riman
dando al cap. 12 l'analisi del terzo tipo.
7.2. Assegnazione aritmetica
Si tratta di una istruzione del tipo:
v = espressione aritmetica
dove v è l'identificatore di una variabile intera, reale, doppia precisione o complessa.
848S
Esempio 7.2. Supponendo che le variabili I, N, A, B contengano i valori:
Negli esempi che seguono supporremo di valutare una espressione reale con una
precisione Ero ::;: 10- 6 e una espressione doppia precisione con Ero ::;: 10- 16.
Esempio 7.1.A = 1.85
1=4
XI = Z
effetto: il valore 1.85 è memorizzato in A
effetto: il valore 4 è memorizzato in I
effetto: il contenuto di Z è copiato in X l.
Esempio 7.5. L'effetto della frase di assegnazione
v = 1./3. + 1./3. + 1./3.
è quello di memorizzare in V il valore 0.999999 dell'espressione reale a destra
del segno =. Se D è il nome di una variabile in doppia precisione il suo contenuto,
dopo l'esecuzione della frase
0= 1.00/3.00 + 1.00/3.00 + 1.00/3.00
è 0.9999999999999999.
I : lO N: 3 A: 1.5 B: 0.5
indichiamo, accanto ad ogni frase di assegnazione, il suo effetto
A=BH = A + 10.5
Esempio 7.3. Supponendo che A e B contengono i valori usati nell'esempio
precedente, l'effetto della esecuzione sequenziale delle frasi:
Esempio 7.7. I = X + Y + ZL'espressione è reale mentre è una variabile intera. Supponendo che sia
X : 4.5, Y: 0.0, Z : 1.0, il valore dell'espressione è 5.5 e ad I viene assegnato
il valore 5 = INT (5.5).
Esempio 7.6. A = 7/3 * K.L'espressione è intera mentre A è il nome di una variabile reale. Supponendo
che K : 3 il valore dell'espressione è 6 e il valore 6.0 = REAL (6) viene memoriz
zato in A.
Il~g__c!~lla v~rilÙ)ik_dicui v è l'identificatore può essere diverso da quello
dell'espressione aritmetica. In questo caso la frase di assegnazione è detta di
assegnazione mista e la sua esecuzione avviene secondo lo schema seguente:
• l'espressione viene valutata in base al tipo degli operandi che la compongono;
\
' il .tipo ~ell'identificatore v non influenza in alcun modo il calcolo dell'espressione
aritmetica;
• il risultato dell'espressione viene automaticamente convertito nel tipo di v
mediante l'opportuna funzione intrinseca di conversione (lNT, REAL, OBLE,
CMPLX) e viene quindi memorizzato nella locazione di nome v (ulteriori det
tagli sulle funzioni di conversione sono dati nel cap. 14).
H: 11.5B : 0.5
il valore 13 di lO + 3 è memorizzato in IPN;
il valore 1.0 di (1.5 + 0.5)/2 è memorizzato in H;il valore 4.0 di 1.5 + (2. * 0.5 + 1.5) è memorizzato
in A:il valore 160 di lO + 150 è memorizzato in I
A: 0.5
è il seguente: con la prima frase viene cancellato il contenuto 1.5 di A e sostituito
da quello di B ovvero da 0.5; con la seconda viene valutata A + 10.5 ovvero
0.5 + 10.5 e il suo risultato Il.O è memorizzato in H. Quindi, dopo l'esecuzione
di queste due frasi si ha:
I = I + 150
IPN = I + N
H = (A + B)/2
A = A + (2. * B + A)
••
Esempio 7.4. Supponiamo che vengano eseguite sequenzialmente le frasi:
N = 2l = N + ll = N + l - 5 * l ** 2
Con la prima istruzione il valore 2 è memorizzato in N: con la seconda viene va
lutata l'espressione intera N + I e il suo valore, 3, è memorizzato in I; con la ter
za viene valutata l'espressione N + I - 5 * I ** 2 ovvero 2 + 3 - 5 * 3 ** 2 il cui
risultato, - 40, è assegnato come nuovo contenuto di I.
b
Esempio 7.8. V = 1.0 - 12 + A.
Supponendo che A e V siano variabili reali e che A : 1.0, l'espressione viene
valutata in doppia precisione in quanto vi compare come operando la costante
I.D - 12. Il risultato dell'espressione doppia precisione .100000000000 10000 + I
viene troncato e memorizzato nella cella V il cui contenuto diviene quindi
.IOOOOOE + OI = REAL (.100000000000 IOOOD + I).
In fig. 7.1 si riassumono le possibili frasi di assegnazione aritmetica mista
previste in F77; si può notare che sono proibite situazioni che prevedono la con-
r86 87
versione doppia precrsione - complesso o viceversa. In F66 sono proibite anche
le frasi di assegnazione mista in cui la variabile v oppure l'espressione aritmetica
sono di tipo complesso.
/espressione realevariabile intera = - espressione doppia precisione
"'--espressione complessa
espressione interavariabile reale =~espressione doppia precisione
"<, espressione complessa
dopo l'esecuzione delle prime due frasi di assegnazione la variabile T I contiene
il valore «vero» mentre T2 contiene il valore «falso». Il contenuto di T I viene
modificato dalla frase successiva. Essa viene eseguita valutando prima il valore
dell'espressione logica TI .AND.T2 che, essendo T2 falso, dà come risultato lo
gico .FALSE.; tale valore viene quindi assegnato come contenuto di T I.
Osserl'azione. Nella pratica si presenta spesso la necessità di scambiare il conte
nuto di due celle di memoria dello stesso tipo. Indicate con A e B le due celle,
la successione di istruzioni
""espressione interavariabile doppia precisione =/
""'-espressione realenon ha l'effetto voluto, che è invece ottenuto dalla successione
/espressione interavariabile complessa =
""'-espressione reale
Figura 7.1. Assegnazioni uitmetiche miste previste in F77.
7.3. Assegnazione logica
E' possibile assegnare il risultato di una espressione relazionale o logica ad una
variabile di tipo logico v mediante la frase:
dove S è il nome di una cella di memoria «ausiliaria» dello stesso tipo di A e B.
in cui si «salva» il contenuto di A per poterlo poi assegnare a B.
In generale, nel seguito, con la frase «scambia A con B» si indicherà una suc
cessione di operazioni del tipo sopra indicato.
v = espressione logica
la cui esecuzione implica la valutazione della espressione indicata e la assegnazione
del suo valore (cvero» oppure «falso») alla variabile logica v.
Esercizi
7.1. Dire quali delle seguenti frasi di assegnazione non sono corrette e perché:
I = 1+ K; 49 = K L = A + B/C; A + C ** 2 = D ;
R = SQRT(X + Y); A + B = 0.5 + H
7.2. Scrivere le opportune frasi di assegnazione per memorizzare la parte intera
del valore di ciascuna delle seguenti espressioni aritmetiche:
7.3. Scrivere le opportune frasi di assegnazione per memorizzare in floating point
i valori delle espressioni dell'esercizio 7.2.
33a -
2j - 5
(sin (x) + cos (x»2
sin 2(x) + cos 2(x)
a+~
LOGICAL TI, T2TI = .TRUE.T2 = .FALSE.TI = TI .AND. T2
LOGICAL VAL, FLAGVAL= .TRUE.FLAG = .FALSE.
dopo l'esecuzione di queste frasi la cella di memoria chiamata VAL contiene il
valore logico «vero» e quella indicata con FLAG il valore «falso».
Esempio 7. 9.
Esempio 7.10.
88
7.4. Dire quale valore è assegnato per effetto delle seguenti frasi:
A = 1/2 + 3.5
M = A/2 + 5/2
M = (A + 5)/2
B = REAL(l)/2 + 3.5
con I : 3
conA:5.
con A :4.
con I : 3.
8Alcuni semplici programmi
7.5. Supponiamo di usare un elaboratore nel quale, dato x, fl(x) è ottenuto
mediante troncamento; dopo l'esecuzione sequenziale delle frasi:
R = 3.
X = l./R
L = 3. * X
M = R * X
N=X+X+X
le variabili L, M ed N contengono il valore zero. Perché?
7.6. Dire quali delle seguenti frasi di assegnazione non sono corrette e perché
(solo i nomi di variabile che iniziano con la lettera L sono di tipo logico):
L = A.AND.LI; A.LT.B + 5. = LA; A = Ll.OR.L2
L = A ** 2.GT.5 ..OR ..NOT.L.; LI = .NOT.(A.RQ.B);
LI = .NOT.(A.EQ.B); A.NE.B = LI; L4 = Ll.AND.(L2.0R.L4).
7.7. Scrivere le opportune frasi di assegnazione di tipo logico per memorizzare
il risultato della valutazione delle seguenti espressioni logiche informali:
«A è maggiore di B e C non è minore di D»
«non LO oppure L l»
<<1 è uguale a l O oppure A è minore o uguale a l.E-5».
7.8. Descrivere tramite frasi di assegnazione le seguenti situazioni:
«L è vera se LI è vera e L2 è falsa, altrimenti è falsa»
«L è falsa se LI è vera oppure A è maggiore di B, altrimenti è vera».
8.1. Introduzione
Abbiamo visto nei capitoli precedenti quali siano gli elementi fondamentali
costituenti le frasi del linguaggio FORTRAN: le costanti e le variabili. Tramite
questi elementi, insieme agli operatori aritmetici, logici e di relazione, si possono
costruire le espressioni. Finalmente, tramite le espressioni, si può realizzare
l'operazione di assegnazione.
Prima di passare ad esaminare altre fondamentali frasi FORTRAN quali quelle
di controllo, vogliamo dare in questo capitolo alcuni esempi di programmi comple
ti per la cui costruzione possediamo già alcuni strumenti. Osserviamo che, avendo
come unica frase eseguibile quella di assegnazione, siamo in grado di scrivere sol
tanto programmi che realizzano una sequenza di calcoli e che portano a definire
il valore di alcune variabili. Tali programmi hanno un senso molto particolare:
essi infatti calcolano sempre gli stessi valori in quanto non possono acquisire dati
di volta in volta diversi e, d'altra parte, non riescono a fornire i risultati calcolati;
in una parola, manca loro l'interfaccia con il mondo esterno costituita dalle opera
zioni di ingresso/uscita. Con le operazioni di ingresso si possono acquisire dati
di volta in volta diversi e con le operazioni di uscita possiamo visualizzare i risul
tati.
Per poter scrivere un programma reale, è infine indispensabile usare delle op
portune frasi che ne indichino la fine. L'inizio di un programma FORTRAN è
invece automaticamente indicato dalla sua prima frase.
8.2. Frasi di ingresso/uscita guidate dalla lista
Nei capitoli 13 e 18 verranno trattate estensivamente le diverse frasi di ingres
so/uscita previste in F77. Per il momento. allo scopo di poter scrivere qualche
semplice programma, mtrocuciarno le frasi di ingresso/uscita guidate dalla lista
(non previste in F(6): csse permettono di leggere dati o visualizzare risultati ser
vendosi delle unità di ingresso () di uscita standard, definite dal sistema di calcolo
Con cui si lavora, senza specificare nel programma il modo in cui i dati o i risultati
r90 91
devono essere forniti.
La frase di ingresso guidata dalla lista ha la forma seguente0.5. Alcune forme in cui i dati possono essere forniti al momento dell'esecuzionedella frase sono le seguenti:
PRINT ., lista-di-uscita
Esempio 8.3. Sono esempi di frasi di uscita guidate dalla lista i seguenti:
(a) 7 15/0.05 0.5(b) 7, 15 /(c) 7
15
/
7 15 0.05 0.57, 15,0.05,0.57, 15.5 E-l, 0.5
7
155.E-2
5.E-l
(a)
(b)
(c)
(d)
La precedente frase di lettura può essere usata per assegnare un valore alle
sole variabili Kl e K2; per questo è sufficiente fornire i dati, ad esempio, in unadelle forme seguenti:
Se si vogliono leggere n valori uguali a una costante c, è possibile scrivere su
una linea un simbolo della forma n. c invece di scrivere n costanti uguali a cseparate da virgole o da caratteri blank.
In analogia con la frase READ ., esiste in F77 la frase di uscita guidata dallalista che ha la forma:
dove:
• PRINT è la parola chiave;
• Iista-di-uscita è una lista di espressioni FORTRAN separate da virgole. Forme più generali di lista-di-uscita sono definite nel cap. 13.
PRINT *, A, BPRINT *, A, B, A + B, A .. 2 - B .. 2PRINT -. N, X, SQRT (DELTA)PRINT -. ABS(X).GT.EPS
L'effetto della frase PRINT. è il seguente: vengono calcolati i valori delle
espressioni che compaiono nella lista; questi valori vengono poi riprodotti sulper assegnare alle variabili K l, K2, X ed Y rispettivamente i valori 7, 15, 0.05,
READ ., lista-di-ingresso
READ., Kl, K2, X, Y
Esempio 8.2. Supponiamo di usare la frase
I dati in lettura possono essere disposti su una o più linee (righe su una tele
scrivente, schede perforate, etc.) e sono separati da caratteri blank o da virgole:
il primo dato inizia con il primo carattere non blank e termina quando compare
un altro carattere blank o una virgola; il secondo dato, se esiste, inizia dal successi
vo carattere non blank e così via. L'esecuzione di una frase di lettura guidata dalla
lista fa sì che vengano lette tante linee quante ne sono necessarie per assegnare un
valore a tutte le variabili della lista. L'operazione di lettura viene però interrotta
se si incontra su una linea un carattere / (sbarra): in questo caso le eventuali
variabili della lista a cui ancora non è stato assegnato un valore, mantengono
quello che avevano prima dell'inizio dell'operazione.
Notiamo infine che ogni operazione di lettura inizia con una nuova linea.
A = 0.01B = -0.001
1=5.
Esempio 8.1. Con l'istruzione
READ .,A, B, I
si leggono dal mezzo di ingresso standard tre valori numerici, due reali e uno inte
ro, che vengono memorizzati nelle celle di nomi A, B, I. Supponiamo ad esempio
che i dati forniti siano, nell'ordine, 0.0 l, - 0.00 l, 5; allora la frase di lettura ha
lo stesso effetto, ai fini della definizione dei valori di A, B, I, delle tre istruzioni
di assegnazione
dove:
• READ è la parola chiave:
• Iista-di-ingresso è una lista di nomi simbolici separati da virgole (forme più
generali di una Iista-di-ingresso verranno viste nel cap. 13).
L'effetto dell'esecuzione della frase READ. è il seguente: vengono letti tanti
valori quanti sono i nomi simbolici presenti nella lista; il primo valore viene asse
gnato alla prima variabile, il secondo alla seconda e così via. I valori in ingresso
devono essere sotto forma di costanti FORTRAN e devono accordarsi in ordine e
tipo con le variabili della lista.
92
mezzo di uscita standard (video, telescrivente, stampante, etc.) in un formato
che dipende dal tipo di ciascuno di essi e dalla particolare realizzazione del
FORTRAN. Così, per esempio, il risultato di un'espressione aritmetica reale può
venir stampato nella forma con o senza esponente in base al suo ordine di gran
dezza: di solito vengono visualizzate un numero di cifre coerente con la precisio
ne di macchina. In ogni caso, in uscita i dati di tipo numerico sono preceduti e
seguiti da caratteri blank che ne facilitano la lettura. Ogni operazione di uscita
inizia su una nuova linea e crea tante linee quante ne sono necessarie per stam
pare tutti i valori previsti dalla lista di uscita.
Esempio 8.4. La frase
PRINT*, X, Y, X - Y
fa sì che vengano riprodotti sul mezzo standard i valori di X e Y e la loro dif
ferenza, risultato dell'espressione X - Y.
Negli esempi che seguono faremo spesso uso di liste di uscita contenenti costan
ti di tipo carattere che sono costituite in generale da una stringa di caratteri
alfanumerici e/o speciali delimitata da apici (cfr. cap. 12). Osserviamo che una
coppia di apici consecutivi all'interno di una costante di tipo carattere viene ri
prodotta in stampa come un unico apice, mentre gli apici che delimitano la
stringa non vengono riprodotti in stampa.
Esempio 8.5. Supponendo che sia A : 2, B : 3 ed R: - 1.5 e che la precisione di
macchina sia dell'ordine di 10- 6 la frase
PRINT., 'LAVSOLUZIONEvDELL"EQUAZIONE', A, '.X+',B, '= O.E"', R
produce la linea di stampa:
LA SOLUZIONE DELL'EQUAZIONE 2.000ooo.X + 3.000000 = O.E' - 1.500000
Se invece è A : 2 x 10 9 , B : 3 x 10 9 ed R : - 1.5 la stessa frase di uscita dà
luogo alla seguente linea di stampa:
LA SOLUZIONE DELL'EQUAZIONE 2000000 E +09.X +3.000000 E +0.9 =O.E' -1.500000
8.3. Le istruzioni PROGRAM, STOP e END
Vogliamo ora scrivere un programma che legga due numeri reali a, b conb
a '* O, calcoli la soluzione r = - - dell'equazione ax + b = O, e la stampi.a
93
PROGRAM RADICIC PROGRAMMA CHE CALCOLA LA SOLUZIONE DELL'EQUAZIONEC AX + B = O CON A.NE.O
READ., A, BR = - B/APRINT., :LAVRADICEVDELL"EQUAZIONE', A, '.X +', B: = OV['"PRINT., ••••• ', R, ' ••••*STOPEND
Nel programma ora scritto compaiono alcune nuove istruzioni: la prima e le
ultime due.
Istruzione PROGRAM
PROGRAM RADICI è la frase che dà il nome (RADlC l) al programma. La
forma generale dell'istruzione PROGRAM è la seguente:
PROGRAM nome
dove:
• PROGRAM è la parola chiave che identifica la frase;
• nome è un nome simbolico che non deve essere usato in nessun'altra istru-
zione del programma.
~a frase PROGRAM non esiste-in F66 e il suo uso in F77 è facoltativo in quan
to Il nome che con essa si assegna serve esclusivamente per distinguere un pro
gramma da un altro.
Quando è presente, la frase PROGRAM deve precedere ogni altra istruzione.
Istruzioni STOP e END
Le ultime due frasi del programma RADIC l ne indicano la fine. La frase costi
tuita ~alla sola parola chiave STOPln~qi(,:~ k[ine logica del programma; la sua
esecuzione fa sì che l'esecuzione del programma termini.
. La frase costituita dalla sola parola chiave END deve essere l'ultima istruzionedi ogni '1' d' .'. 111 UI1l a .1 programma; essa e ~I1.~)ras~ non eseguibile ed ha lo scopo di in-
dicare al compilatore la fine fisica dell'unità di programma.
Osserviamo che in F77, ma non in F66. la successione di istruzioni
STOP
END
è equivalente alla sola Istruzione END.Osservi. . I h"rviarno 1110 tre c e 111 un programma possono essere presenti più frasi
STOP, se è richiesta l'interruzione dell'esecuzione in più punti distinti,
La frase STOP può essere usata anche nella forma
STOP n
b _
94
dove n è una costante intera costituita al più da 5 cifre (o, in F77, una costante
di tipo carattere). Quando l'istruzione STOP n viene eseguita, la costante n èdisponibile per qualche scopo dipendente dalla particolare realizzazione del
FORTRAN; di solito essa viene visualizzata sul mezzo standard di uscita e può
servire per individuare in Quale punto il programma è terminato quando vi siano
più punti di uscita.,
'I Riassumendo, in un programma scritto in F77 possono esserci nessuna, una, ~
/
. o più frasi STOP, mentre deve essercene almeno una se il programma è scritto in .
F66. In ogni caso ogni unità di programma deve terminare con la frase END.
In fig. 8.1 sono riportate le modificazioni dello stato della memoria dovute
all'esecuzione del programma RADICI, nell'ipotesi che i valori letti siano a = 0.01
e b = 83.24 e che la precisione di macchina sia dell'ordine di 10-6 .
r95
Esempio 8.6. Un risultato analogo a quello del programma RADICI per quanto
riguarda la gestione delle operazioni di ingresso/uscita, ma non per quanto riguar
da la memoria, si ottiene con il seguente programma.
PROGRAM RADIC2READ -. A, BPRINT *, 'LAvRADICEvDELL"EQUAZIONE', A, '*X +', B: = OvE'"PRINT *, '****., - B/A, '****.STOPEND
In questo programma manca l'assegnazione alla variabile R del valore - B/A,
che invece viene direttamente stampato per effetto dell'ultima frase PRINT.
8.4. L'istruzione PARAMETER
Memoria
A B R ...
- - - -
rno.ou n(83.24) - -
nro.on n(83.24) 11(- 8324.) -
nro.on 11(83.24) n(- 8324.) -
n(OOI) n(83.24) 11(- 8324.) -
Stato iniziale
Dopo l'esecuzione della frase READ
Dopo l'esecuzione della frase R = - BIA
Dopo l'esecuzione delle frasi PRINT
Stato finale, al momento dell'esecuzionedella frase STOP
Supponiamo di voler scrivere un programma in cui. dato un valore x > I, sicalcola e si stampa il valore y = f(x), con
I+n'f( x) = x 2 - 2 n'x + -- - 2 n'
Inx
dove n' è un parametro reale che per il momento fissiamo uguale a 0.1. Il risul
tato desiderato può essere ottenuto con uno dei due programmi seguenti:
PROGRAM ALFAIREAD -. Xy = X * X - 2. * 0.1 * X + (1. + O.1)/LOG(X) - 2. * 0.1PRINT -. 'X = t x.v =', YSTOPEND
Dati in ingresso
0.01 83.24
Linee di stampa
LA RADICE DELL'EQUAZIONE O.OiOOOO *X + 83.24000 = O E'- 8324.000 *****
figura 8.1. Esecuzione del programma RADIC 1.
PROGRAM ALF A2ALFA = 0.1READ -. X
Y = X * X - 2. * ALFA * X + (l. + ALFA)/LOG(X) - 2. * ALFAPRINT *,'X =', x.v = " YSTOPEND
La differenza principale fra i due programmi è la seguente: in ALFA I si è in
serito il valore 0.1 direttamente nell'espressione FORTRAN il cui risultato viene
memorizzato in Y; in ALFA2 si è introdotta una variabile, ALFA, a cui si assegna
96
il valore 0.1, e che viene usata nell'espressione. E' ovvio che ALFA2 è un pro
gramma più flessibile di A LF Al; infatti è possibile usarlo per valori diversi del
parametro Q' semplicemente intervenenuo sulla frase di assegnazione ALFA = 0.1,
anzichè sulla frase, ben più complessa, che definisce Y. In F77 è possibile defi
nire ALFA come nome simbolico della costante 0.1 mediante la frase dichiara
tiva PARAMETER, la cui forma è la seguente:
cC
PROGRAM CERCHIOSTAMPALA LUNGHEZZA DELLA CIRCONFERENZAE L'AREA DEL CERCHIOPARAMETER (PI = 3.141592, DUEPI = 2. * Pl)READ -. RAGGIOPRINT -. 'RAGGIO =', RAGGIOPRINT *, 'LUNGH.vCIRCONFERENZA = ,DUEPI * RAGGIOPRINT -. 'AREA =', PI * RAGGIO ** 2STOPEND
97
dove:• PARAMETER è la parola chiave che identifica la frase;
• Pl"'" Pn sono nomi simbolici;• e
l, ... , e
nsono espressioni costanti (cfr. §6.4). Se P j è di tipo carattere, logi-
co, o numerico, ei
deve essere di tipo carattere, logico o numerico rispettivamente.
Per effetto dell'istruzione PARAMETER, il nome Pi è un nome simbolico di
costante il cui valore è il risultato dell'espressione e i che gli viene associato se
condo le regole dell'assegnazione. Se in un'istruzione PARAMETER compare
un'espressione contenente un nome simbolico di costante, questo deve essere
stato definito precedentemente nella medesima o in un'altra frase PARAMETER.
Un nome simbolico di costante è un nome di costante a tutti gli ~!'fet~!
avendo la «forma» di un nome di variabile; esso può quindi essere usato in una
frase FORTRAN allo stesso modo di una costante, salvo il fatto che non può
essere parte di una costante (ad esempio, parte reale o parte immaginaria di una
costante complessa), e neppure di una specificazione di formato (cfr. cap. 13).
Si osservi inoltre che, in quanto nome di costante, il valore di un nome simbo-I
{\'i lico di costante non può essere modificato mediante, ad esempio, frasi di asse-I \\
gnazione o di lettura o mediante altre frasi PARAMETER. I.In quanto dichiarativa, l'istruzione PARAMETER deve precedere tutte le frasi
eseguibili dell'unità di programma in cui compare. Per quanto riguarda la posizio
ne della PARAMETER rispetto alle altre frasi dichiarative, si veda l'appendice
A3.
Esempio 8. 7. Sono esempi corretti di utilizzo della istruzione PARAMETER i
seguenti:
LOGICAL VERO, FALSOPARAMETER (VERO = .TRUE., FALSO = .FALSE)PARAMETER (EPSM = lE ~ 06, EPS = IO *EPSM)PARAMETER (ALFA = 0.1, BETA = ALFA * EPS)
Esempio 8.8. Nel programma seguente SI definiscono i due nomi simbolici di
costante l'I e DUEPI; eSSI vengono usati nelle espressioni aritmetiche che figurano
nelle istruzioni di stampa.
L
8.5. Altri esempi
Vediamo qualche altro semplice programma in cui si utilizzano le frasi
FORTRAN fin qui incontrate.
Esempio 8.9. Dati due numeri II' 12 > O si vuoi calcolare e stampare l'area ed il
perimetro del rettangolo di lati II e 12 e del quadrato di lato uguale al minimo fra
Il e 12,
PROGRAM GEOMREAL LATOI, LATm, LATO
C LETTURA DEI DATIREAD *, LATOI, LATm
C CALCOLO DEL PERIMETRO E DELL'AREA DEL RETTANGOLOPRETT = 2. * (LATOI + LAT02)ARETT = LATOI * LAT02
C CALCOLO DEL PERIMETRO E DELL'AREA DEL QUADRATOLATO = MIN (LATOI, LAT02)PQUAD =4. * LATOAQUAD = LATO * LATO
C STAMPADEI RISULTATIPRINT *, 'ILvPERIMETROvDELvRETTANGOLOvDIvLATI'
LATOI, LAT02, 'E":', PRETT 'PRINT *, 'LAvSUAVAREAvE":', ARETTPRINT *, 'ILvPERIMETROvDELvQUADRATOvDI LATO', LATO,
'E":' PQUADPRINT *, 'LAVSUAVAREAVE":', AQUADSTOPEND
Esempiu 8. JO Il seguente programma calcola un valore approssimato per sen x,
dove x è espresso in radianti, come somma dei primi cinque termini dello sviluppo
111 serie di potenze
Lx2k ~ I x3 x5 x7 x'l
se n x = (- l )k X - - + - + --
k=O (2k + l)' 3' 5' 7' 9'
(98
ccc
PROGRAM SENOAPPROSSIMAZIONE DEL SENO DI UN ANGOLO DIX RADIANTI TRAMITE LA SOMMA DEI PRIMI CINQUETERMINI DELLO SVILUPPO IN SERIE DI POTENZE
PRINT ., 'SCRIVlvILvVALOREvDlvX vINvRADIANTI'READ., XTI =XT2 = TI • X/2.• X/3.T3 =T2 • X/4.• X/S.T4 = T3 • X/6. • X/7.T5 = T4 • X/8.• X/9.PRINT., 'ILvSENOvDl', X, 'E" CIRCA'PRINT., 'u., TI - T2 + T3 .- T4 + T5, '•••STOPEND
r99
dove ft x) è definita da:2- n
8.4. Individuare gli eventuali errori nelle seguenti frasi:
PARAMETER (RAD 2 = SQRT (2.»
PARAMETER (EINV = l./E, E = 2.7182)
PARAMETER (SO M = 0.5, UNO = r., ZERO = O)
PARAMETER (N = in N2 = N. N)
8.5. Indicare i valori delle variabili A, B, N, NP e J dopo l'esecuzione della frase
Si noti che l'esecuzione di questo programma è prevista in modo interattivo,
in quanto la prima istruzione prevede la stampa sul mezzo standard del messaggio
SCRIVI IL VALORE DI X IN RADIANTI
Tale messaggio informa l'utente che deve fornire il dato (ossia, il valore attuale di
x) necessario per l'esecuzione della successiva operazione di lettura. Ovviamente,
l'esecuzione non procede finchè tale dato non è stato fornito.
Esercizi
8.1. Dette A e B la base e l'altezza di un tnangolo, scrivere un programma che
legga i valori di A e B e stampi l'area del triangolo.
8.2. Se a, b e c indicano le lunghezze dei lati di un triangolo, la sua area può
essere calcolata con la formula
s = Vp(p - a) (p - b) (p - c)
nove p è il semiperimetro del triangolo.Scnvere un programma che, letti I valori di a, b e c calcoli e stampi il pen
metro e l'area del triangolo.
8.3. Scrivere un programma che, dati i valori a, b ed n, calcoli e stampi il valore
b-a[ (b-a) J-6- f(a) + 2 f -2- + f(b)
READ ., A, N, B, NP, J
supponendo che i dati siano forniti in uno dei modi seguenti:
(a) 7.3, l O, - 3.5, 87, 1010
(b) 7.3, 10/
(c) 73., l, O., O, O
(d) - lO E - 3
737
S. E-S, 102, -3(e) + 7.03 E + 2, - 38, 5.5, lO
- 78
(O 1.1.1,2.2,2,3,8,15
8.6. Se zI = 1.1 + 3i, z2 = 5 + 8i e z3 = i sono tre numeri complessi, scrive
re un programma che calcoli e stampi la loro somma ed i loro moduli.
8.7. Scrivere un programma che calcoli e stampi la somma ed il prodotto di due
numeri complessi assegnati.
8.8. Supponiamo che le istruzioni
REA L A, N
COMPLEX OMEGA
DOUBLE PRECISION B
READ.,A,N,OMEGA,B
facciano parte della stessa unità di programma. Indicare come devono essere
fomiti i dati perché dopo l'esecuzione della frase di lettura le variabili A.
N. OMEGA e B abbiano tutte valore zero.
9Scelte e decisioni
9.1. Controllo esplicito dell'esecuzione: l'istruzione GOTO-incondizionato
La sequenzialità del flusso di un algoritmo può essere interrotta in situazioni
che impongono la scelta tra blocchi di istruzioni alternativi in base al verificarsi
o meno di una determinata condizione. Queste situazioni di scelta vengono de
scritte in FORTRAN mediante opportune istruzioni che sono l'argomento dei
prossimi paragrafi e che, insieme alle strutture di ripetizione che verranno presentate nel prossimo capitolo, permettono di controllare quasi completamente l'e
secuzione di un programma. Esistono però situazioni che richiedono un controlloesplicito dell'esecuzione del programma. Tale controllo viene realizzato mediantel'istruzione GO TO-incondizionato.
Questa istruzione ha la forma seguente:
GOTOn
dove:
• GO TO è la parola chiave;• n è l'etichetta di una frase eseguibile che deve essere presente nella stessa unità
di programma cui appartiene l'istruzione GO TO-incondizionato.
L'esecuzione della frase GO TO n provoca il trasferimento del controllo della
esecuzione all'istruzione la cui etichetta coincide con n. Così, per esempio, l'ese
cuzione delle istruzioni:
N=lGO TO io
9 N=N+lOO
lO J = N + 30
avviene nel modo seguente: si pone uguale ad uno il contenuto della cella N el'esecuzione prosegue poi, sequenzialmente, a partire dall'istruzione individuatadall'etichetta numero lO. L'istruzione intermedia N = N + 100 viene completamente ignorata.
I"
IO.
102 103
Esempio 9.1. Sia f(x) una funzione reale di variabile reale definita da:
Supponendo noto il valore di x si vuoI calcolare la Quantità v = f(x) + x2.
La situazione di scelta relativa a questo problema è la seguente:
dove c è un'espressione logica il cui valore. valutato al momento dell'esecuzione
dell'istruzione IF (c) THEN. determina la scelta tra i due blocchi di istruzioni.
L'effetto deIl'esecuzlOne di questa struttura è esattamente quello indicato in
fig. 9.1: se la condizione indicata dalla espressione c è vera vengono eseguite
le istruzioni del blocco l e sono ignorate quelle del blocco 2 mentre, se la condi
zione c è falsa vengono eseguite soltanto le istruzioni del blocco 2. In entrambi
i casi l'esecuzione continua con l'istruzione che segue immediatamente END IF.
La struttura decisionale IF-THEN-ELSE è quindi caratterizzata da una frase
iniziale IF (c) THEN e da una frase finale END IF. La frase intermedia ELSE
serve ad evidenziare sia la fine del primo blocco di istruzioni che l'inizio del se
condo. Il primo blocco, detto anche b!-occo_'I!1~~, è costituito da tutte le istru
zioni che seguono IF(c) THEN e precedono ELSE mentre il secondo, detto
anche blocco ELSE:_' è costituito da tutte le istruzioni che seguono ELSE e pre-
'cedono END IF. Siosservi che, in quanto eseguibile, la frase ELSE può avere unall j
,',\ etichetta ma è proibito farvi riferimento mediante altre frasi di controllo. ;' i
per x ~ 1.5
per x < 1.5l x-l
f(x) = ~ OIF (c) THEN[blocco di istruzioni 1] +- (blocco THEN)
ELSE[blocco di istruzioni 2] +- (blocco ELSE)
END IF
E' importante osservare che l'istruzione GO TO-incondizionato deve essere
usata in modo opportuno: infatti un suo uso eccessivo e indiscriminato dà luogo
a programmi di difficile lettura e comprensione.
L'analisi fatta sugli algoritmi e la loro descrizione ha messo in evidenza la ne
cessità di strutture che, in presenza di più blocchi di istruzioni alternativi. per
mettano di sceglierne uno in base alla veridicità o meno di una particolare condi
zione. In F77 è possibile tradurre una situazione di scelta tra due blocchi alterna
tivi mediante il costrutto IF-THEN-ELSE. Un'analisi dettagliata di questo costrut
to, non previsto nelle precedenti versioni del FORTRAN, facilita la comprensione
di un'altra istruzione che può essere usata in un processo decisionale e che è pre
vista anche in F66: l'istruzione IF-logico.La generica situazione di scelta tra due blocchi di istruzioni alternativi può
essere schematizzata nel modo illustrato in fig. 9.1. Ad essa corrisponde la strut
tura di controllo
9.2. Costrutto IF-THEN-ELSE
Bloccodiistruzioni
2
IF (X.GE.I.5) THENY=X-1.ELSEY=O.ENDIFY=Y+X .. 2
Figura 9.1. Scelta tra due blocchi di istruzioni.
104
Esempio 9.2. Siano x ed y due numeri dati e diversi da zero. Se x ~ y si cal
colano le quantità s = x + y e p = xy, altrimenti si calcolano d = x - y e
q = d/(2 y).
Questa situazione può essere così descritta:
IF (X.GE.Y) THENS=X+YP=X.YELSED=X-YQ= D/(2. • Y)ENDIF
Si noti che è proibito trasferire il controllo dell'esecuzione di un programma
,·r dentro unblocco TH}:N oppure dentro u~-b/oc~~ ELSE~9uindi, ad esempio,
è sbagliato scrivere una successione di istruzioni come la seguente:
GO TO IO
IF (X. GE. Y) THEN
S=X+YlO Y=S.X
ELSE
A=X-YENDIF
Figura 9.2. Strutture decisionali mancantidel blocco TREN.
La struttura
IF (c) THEN
ELSE
[blocco di istruzioni]
ENDIF
corrisponde al diagramma di fig. 9.2 mentre
IF (c) THEN
[blocco di istruzioni]
ELSE
ENDIF
IOS
Figura 9.3. Strutture decisionali mancantidel blocco ELSE.
In queste istruzioni infatti la frase GO TO IO trasferisce il controllo dell'ese
cuzione dentro un blocco THEN.
In altre parole si può dire che in F77 non è permesso «entrare», mediante una
frase di controllo, dentro una struttura di scelt,!;~~~IQQ~rmt2~Q «!!~çrr-e-12_da una.
struttura di questo tipo mediante opportune istruzioni di controllo eventual!12~e
presenti in un blocco THEN o in un blocco ELSE. In una situazione di questo
genere viene allora a mancare l'ipotesi, che generalmente accompagna una struttu
ra decisionale, e che consiste nel presupporre che, scelta la strada da seguire, l'e
secuzione prosegua con l'istruzione successiva a quella finale della struttura stessa.
La presenza di una istruzione di controllo dentro una struttura decisionale può
quindi compromettere la leggibilità di un programma e la possibilità di seguirne
facilmente il flusso.
Una struttura decisionale deve prevedere anche situazioni in cui li/W dei dueblocchi THEN oppure ELSE è vuoto ovvero le situazioni rappresentate nelle
figu re segue nti:
corrisponde a quello di fig. 9.3. Quando il blocco ELSE è vuoto l'istruzione
ELSE può essere omessa. Si osservi che le situazioni rappresentate dalla fig. 9.3
sono equivalenti a quelle di fig. 9.2: basta esprimere in modo opportuno la con
dizione che determina la scelta.
9.3. Strutture decisionali annidate
I blocchi di istruzioni che compaiono nella struttura lF-THEN-ELSE possono
a loro volta contenere altre strutture di scelta; è quindi possibile avere più costrut
ti IF-THEN-ELSE uno dentro l'altro ciascuno dei quali deve essere chiuso da una
istruzione END IF. Situazioni di questo tipo vengono dette strutture annidatemtendendo per nido ael costrutto decisionale IF-THEN-ELSE tutte le istruzioni
comprese tra la frase iniziale lF (c) THEN e quella finale LNU IF.
Negli esempi seguenti. i nidi delle strutture di controllo sono stati evidenziatigraficamente mediante parentesi quadre
---j",---------------------~
106107
Esempio 9.3. La trascrizione in F77 delle istruzioni indicate in fig. 9.4 è la se
guente:
Esempio 9.4. Dati i coefficienti reali a. b. c di una equazione di secondo grado
ax2 + bx + c == O si selezionano. mediante l'indicatore ind. diversi casi:
ind == - 2
ind == - I
ind == O
ind == I
significa che l'equazione è del tipo c == O:
significa che l'equazione è del tipo bx + c == O:
significa che l'equazione è del tipo ax 2 + bx + c == O ed ha radici reali;
significa che l'equazione è del tipo ax 2 + bx + c == O ed ha radici com
pIesse coniugate.
In fig. 9.5 si riportano il diagramma di flusso e le relative istruzioni F77.
IF (A.EQ.O.) THENIF (B.EQ.O.) THEN
~IND =-2ELSEIND == -- lENDIFELSEDELTA==Bu2 -4.*A*CIF (DELTA.GE.O.O) THEN
[
IND = OELSEIND= lENDIFENDIF
Figura 9.5. Diagramma di flusso e istruzioni corrispondenti all'esempio 9.4.
Le parentesi quadre che accompagnano la lista delle istruzioni FORTRAN
negli esempi 9.3 e 9.4 servono soltanto a mettere in evidenza gli annidamenti di
più strutture IF-THEN-ELSE: esse non fanno certo parte del programma ma ne
facilitano la comprensione. E' possibile ottenere un risultato analogo incolonnan
do le istruzioni relative ai nidi delle strutture di controllo più interne su posizioni
via via più spostate a destra; questo modo di incolonnare le istruzioni viene di
solito indicato con il termine inglese indentation (intaccatura, dentellatura) e
verrà utilizzato negli esempi che seguono~-Figura 9.4. Diagramma di flusso corrispondente all'esempio 9.3.
IF (J.LE.N) THENJ = N +JIF (X.GE.O.S) THEN
lS = X + TT =J. SELSES=X-TT = 3. * S ..2ENDIFT==T+XELSES==J*XIF (X.GT.O.O) THEN
[
T == SQRT(S)ELSET==-SENDIFX=T+SEND IF
, II
, i
Figura 9.6. Diagramma a blocchi e programma corrisponuente all'algoritmo deU'esempio 9.5.
Esempio 9.5. L'area di un triangolo i cui lati hanno lunghezze a, b, c è data dalla
formula di Erone s =vq dove q = p(p - a) (p - b) (p - c) con p = (a + b + c)/2.
Evidentemente tre valori a, b, c non rappresentano la lunghezza dei lati di un
triangolo reale se non sono positivi oppure se la quantità q non è positiva (esem
pio a = l, b = 3, c = 5). Supponendo di avere più teme di valori di cui almeno
la prima costituita da valori positivi tali che q > 0, scrivere un programma che
permetta di calcolare e stampare il numero «tot» delle teme lette. il numero
«n» di triangoli reali e la loro area media. Il programma termina quando si legge
una tema i cui elementi non sono tutti positivi.
108
PROGRAM ARMEDIINTEGER TOTTOT =0N =0SOM =O.
IO READ •. A. B. CTOT = TOT + IIF (A.GT.O..AND.B.GT.O..AND.C.GT.O.) THEN
P = (A + B + Cl/2.Q = p .(P - A) • (P - Dj. (P - C)IF (Q.GTO.O) THEN
N =N + IS = SQRT(Q)
ELSES =0.
ENDIFSOM=SOM+SGOTO IO
ELSEAM= SOM/NPRINT •. ·SU'. TOT. 'TERNE DI VALORI'PRINT •. N. 'SONO LATI DI TRIANGOLI REALI'PRINT •. 'l"AREA MEDIAE" DATA DA!. AM
END IFSTOPEND
101 On O
SOI11 0
/
109
E' possibile risolvere questo problema con l'algoritmo seguente dove «sorn» in
dica la somma delle aree dei triangoli e la doppia numerazione evidenzia le istru
zioni interne alla struttura decisionale.
l. Poni tot = 0, n = O, som = O
2. leggi: a, b, c
3. incrementa di l il valore di tot4. se i tre valori letti sono positivi
allora: 4.1. calcola p = (a + b + c)/2 e q = p(p - a)(p - b)(p - c)
4.2. se q> Oallora: calcola s =vq, incrementa di l il valore di n
ed esegui 4.3.
altrimenti: poni s = Oed esegui 4.3.
4.3. aggiungi s a som
4.4. vai a 2.
altrimenti: esegui 5.
5. calcola l'area media am = sorn/n
6. scrivi: tot, n, am7. Stop
La lista del programma e il diagramma a blocchi sono dati in fig. Y.6.
Esempio 9.6. Scrivere un programma che risolva lo stesso problema dell'esem
pio precedente prevedendo la possibilità. che, tra tutte le teme lette, nessuna rap
presenti i lati di un triangolo reale: questo caso viene segnalato in fase di stampa
dei risultati.
Il problema può essere risolto mediante il seguente algoritmo:
l. Poni tot = O, n = O, som = O2. leggi: a, b, c
3. incrementa di l il valore di tot
4. se i tre valori letti sono positiviallora: 4.1. calcola p = (a + b + c)/2 e q = p(p - a)(p - b)(p - c)
4.2. se q> O allora: calcola s =~ incrementa di l il valore di n
ed esegui 4.:;
altrimenti: poni s = O ed esegui 4.3
4.3. aggiungi sa som
4.4. esegui 2.
altrimenti: se n> O allora: calcola am = som/n;scrivi: tot, n, am ;
esegui 5.
altrimenti: scrivi: tot ed esegui 5.
5. Stop.
~-----------
p---------------llO
La lista del programma è la seguente:
III
La lista del programma e il diagramma a blocchi sono i seguenti:
!1
PROGRAM ARMED2INTFGER TOTN=OSOM=0.0TOT=O
lO READ *, A, B, CTOT =TOT + IIF (A.GT.O..AND.B.GT.O..AND.C.GT.O.) THEN
P = (A + B + C)/2.Q = p * (P - A) * (P - B) * (P - C)IF (Q.GT.O.O) THEN
N=N + IS = SQRT (Q)
ELSES =0.0
END IFSOM =SOM +SGOTO IO
ELSE--IF (N.GT.O) THEN
AM = SOM/NPRINT *, 'SI SONO LETTE', TOT, 'TERNE DI VALORI'PRINT *, N, 'SONO RISULTATE LATI DI TRIANGOLI REALI'PRINT e , 'L"AREA MEDIA E" DATA DA:', AM
ELSEPRINT *, 'SI SONO LETTE', TOT, 'TERNE DI VALORI'PRINT *, 'NESSUNAINDIVIDUAUN TRIANGOLO REALE'
ENDIFENDIFSTOPEND
Esempio 9.7. Si vogliono ordinare tre valori dati a, b, c in modo che sia a ~ b ~ c.
Un algoritmo per risolvere questo problema è il seguente:
l. Leggi: a, b, c2. se a ~ b allora: esegui 3.
altnmenti: scambia a con b ed esegui 3.
3. se b ~ c allora: esegui 4.altrimenti: scambia b con c
se a ~ b allora: esegui 4.altrimenti: scambia a con b ed esegui 4.
4. scrivi: a. b, c5. stop.
PROGRAM ORDABCREAD *. A, B, CIF (ALE.B) THENELSE
S=AA=B8=S
END IFIF (B.LE.C) THENELSE
S=BB=CC=SIF (A.LE.B) THENELSE
S=AA=BB=S
END IFEND IFPRINT-. A, B, CSTOPEND
9.4. Strutture decisionali concatenate
Nella pratica si presentano spesso situazioni di scelta in cui intervengono più
condizioni che si escludono a vicenda ovvero situazioni che sono descritte da una
costruzione del tipo:
se: condizione 1 allora:esegui l'azione l
altrimenti se: condizione 2 allora:
esegui l'azione 2
altrimenti se: condizione n allora:
esegui l'azione naltrimenti: esegui l'azione n + 1.
112 113
Figura 9.7. Strutture decisionali concatenate.
se x < OseO~x~1
se x> l
x2
x(x - l)
x+2y = f(x) e f(x) =
IF (X.LT.O.O) THENY=X**2
ELSE IF (X.LE.l.O) THENY = X • (X - 1.0)
ELSEY=X +2
END IFS=Y+H
Le istruzioni seguenti:
Esempio 9.8. Dati i valori x ed h si vuoi determinare la quantità s = y + h dove
F
Blocco diistruzioni
n + l
Blocco diistruzioni
n
Blocco diistruzioni
2
Blocco diistruzioni
Tali processi decisionali, visualizzati in fig. 9.7, vengono descritti in F77 me
diante la struttura:
IF (cl) THEN
[blocco di istruzioni l]ELSE IF (c 2 ) THEN
[blocco di istruzioni 2]
ELSE IF (cn
) THEN
[blocco di istruzioni n]
ELSE[blocco di istruzioni n + l]
END IF
dove cl' c2
' ..., cn
sono espressioni logiche che vengono valutate in sequenza
nell'ordine in cui esse compaiono; non appena una di esse risulta vera viene eseguito il blocco di istruzioni che la segue mentre se nessuna espressione risulta
vera è eseguito il blocco di istruzioni che segue la frase ELSE.Si osservi che ogni blocco di istruzioni che segue una delle frasi lF (c l) THEN
oppure ELSE IF (Ci) THEN è implicitamente seguito da un trasferimento allafrase finale END IF della struttura. Risulta quindi importante l'ordine in cui compaiono nella struttura decisionale le singole espressioni logiche in quanto. tra piùespressioni vere, è la prima quella che comanda l'esecuzione della struttura.
hanno l'effetto indicato in fig. 9.8: si valuta la prima espressione X.LT.O.O;
se essa risulta vera si pone Y uguale ad X ** 2 e l'esecuzione riprende dalla istruzione che segue END IF ovvero S = Y + H (in questo caso avremo s = x2 + h).
Se invece la prima espressione risulta falsa si valuta la seconda ovvero si stabiliscese x è minore o uguale ad l. Nel caso in cui questo risulti vero si pone Y uguale ad
X * (X - l.) e l'esecuzione riprende con l'istruzione S = Y + H che in questo casoequivale a s = x(x - l) + h. Se nessuna delle due espressioni logiche precedentiè vera si pone Y uguale ad X + 2. e l'esecuzione continua ancora con S = Y + H
che in questo caso equivale a s = x + 2 + h.
y..-x+2
Figura 9.8. Diagramma di flusso relativo all'esempio 9.8.
114115
9.5. Riepilogo
Da quanto detto fino ad ora segue che una qualunque struttura decisionale
è aperta dalla istruzione
IF (c) THEN
e chiusa da
END IF
Tra queste due frasi possono comparire una o più istruzioni
IF (l.LE.O) THEN
N=OELSE IF (J.GT.IO) THEN
N=3ELSE IF (J.LE.S) THEN
N = lELSE
N=2ENDIF
ELSE IF (c) THEN
ELSE
ENDIF.
può essere sostituita dalla sola
PROGRAM ORDABC
READ -. A, B, CIF (A.GT.B) THEN
S=AA=BB = S
END IF
IF (B.GT.C) THENS=BB=CC=SIF (A.GT.B) THEN
S=AA=BB =S
END IFEND IFPRINT • A, B, CSTOPEND
permettono di calcolare correttamente il valore di N in quanto verrà eseguita
una sola frase di assegnazione, quella corrispondente alla prima espressione logica
che risulta vera; se tutte le espressioni sono false si esegue l'istruzione che segue lafrase ELSE.
Esempio 9.10. Il programma relativo all'esempio 9.7 può essere così modificato:
se J < O
se 1 < J < 5se6<J<IO
se J > lO
N vale O
N vale 1N vale 2N vale 3
ELSE
ENDIF
che deve sempre seguire le eventuali ELSE IF presenti. Le frasi IF (c) THEN,
ELSE IF (c) THEN, ELSE sono seguite da blocchi di istruzioni la cui esecuzione
è subordinata alla veridicità delle espressioni logiche presenti nella struttura e che
possono a loro volta contenere altre strutture decisionali. Ogni blocco di istruzio
ni che segue una delle frasi IF (c) THEN, ELSE IF (c) THEN, ELSE può essere
vuoto ovvero privo di istruzioni. Ricordiamo che se è vuoto il blocco che segue
la frase ELSE è possibile omettere l'istruzione ELSE stessa ovvero la successione
di istruzioni
ed al più una istruzione
Esempio 9.9. Sia N una variabile intera il cui valore deve essere determinato in
base a quello di un'altra variabile intera J secondo le regole seguenti:I!Il;
!Le istruzioni seguenti:
§!.empio 9.11. Dati tre valori reali a, b, c calcolare e stampare M = max (a b c)ed m = rnin (a, b, c) , ,
116
PROGRAM MAXMIlREAL MAX,MINREAD -. A, B, CIF (A.GT.B) THEN
MAX=AELSE
MAX=BEND IFIF (C.GT.MAX) THEN
MAX=CEND IFIF (A.GT.B) THEN
MIN = BELSE
MIN=AEND IFIF (C.LT.MIN) THEN
MIN=CEND IFPRINT *, 'MASSIMO .: MAX,'MINIMO =', MIN
END
Si osservi che, quando il blocco ELSE è vuoto, non si ottiene nessun migliora
mento del programma dalla omissione della frase ELSE, anzi tale omissione può
rendere meno chiaro e leggibile il programma.
9.6. lf-logico: una struttura particolarmente semplice
Supponiamo di voler descrivere in FORTRAN una situazione nella quale unasola istruzione, che chiameremo istruzione dipendente, deve essere eseguita oppure ignorata in base alla veridicità o meno di una condizione (cfr. fig. 9.9).
Il costruHo
IF (c) THENistruzione dipendenteELSEEND IF
produce l'effetto desiderato in quanto l'istruzione viene eseguita se (e soltanto
se) la condizione c risulta vera altrimenti essa viene ignorata.Questa situazione può essere scritta in modo più sintetico nella forma
IF (c) istruzione dipendente
117
F
Figura 9.9. Diagramma corrispondente alla istruzione If'-logìco.
alla quale si dà il nome di IF-Iogico. L'esecuzione di questa istruzione, presentesia in F77 che in F66, ha quindi l'effetto seguente: si valuta l'espressione logica c;se essa risulta vera viene eseguita l'istruzione dipendente altrimenti tale comandoviene ignorato. In ogni caso l'esecuzione continua con l'istruzione che segue l'IF
logico.Sono esempi di istruzioni IF-Iogico i seguenti:
IF(J.NE.IO) SUM=O.IF (ABS(X - Y).LE.EPS) X = XI + SQRT (A + B)IF (X.GT.Y.OR.H.LE.l.E - 3) JMAX = 20
L'istruzione dipendente che accompagna un IF-Iogico non deve essere né un al- ,
tra IF-Iogico nè una delle seguenti istruzioni: IDO, IF (c) THEN, ELSE IF (c) THEN, ELSE, END IF, END. !
Esempio 9.12. Siano dati N valori della variabile A ciascuno dei quali è numeratomediante un numero progressivo I, l E;;; I E;;; N. Si vuoi calcolare quanti valori di
A sono maggiori di UfO.
Se indichiamo con NP il numero totale dei valori positivi di A il problema può
essere risolto dal programma seguente:
PROGRAM NPOSI~EAD *, NNP=O
100 READ *, l, AIF (A.GT.O.O) NP = NP + 1IF (I.EQ.N) STOPGO TO 100END
1-
II~Il:i
I(~
118
Si osservi che il valore di NP ovvero il numero dei valori positivi viene incre
mentato di una unità se A> O; il controllo IF(I.EQ.N) viene invece eseguito sem
pre qualunque sia il valore di A. 1\ programma termina, mediante l'esecuzione
della frase STOP, quando sono stati esaminati tutti i valori di A ovvero quando I
è uguale ad N; se I < N l'esecuzione prosegue con la lettura del successivo valore
di I e di A. Da notare che il programma non prevede la scrittura del valore finale
di NP; qualora essa venisse richiesta due azioni dovrebbero essere eseguite alla fine
della lettura dei dati: la scrittura del contenuto di NP e l'interruzione dell'esecu
zione del programma. Tali comandi non possono essere realizzati mediante una
sola istruzione e quindi il programma scritto deve essere modificato, per esempio,
nel modo seguente:
PROGRAM NPOS2
READ *, N
NP=O100 READ *, I, A
IF (A.GT.O.) NP = NP + 1IF (I.NE.N) GO TO 100
PRINT *, NPSTOP
END
Questo esempio mette in evidenza che l'efficacia della frase di controllo IF..
logico è ~~te~oim~~t~li~itata dal fatto che, quando risulta vera la condizione-in
dicata nell'istruzione stessa, si può eseguire un solo comando: \'istruzione dipen
dente. Per questo motivo, per realizzare senza il costrutto IF-THEN-ELSE una
situazione di scelta tra due blocchi alternativi di istruzioni, si deve utilizzare insie
me all'IF-logico l'istruzione GOTO incondizionato. A questo proposito vediamo
come devono essere modificati alcuni degli esempi di questo capitolo senza far
uso del costrutto IF-THEN-ELSE.
Esempio 9.13. Le istruzioni dell'esempio 9.8 equivalgono a:
IF (X.LT.O.O) GO TO 100IF (X.LE.I.O) GO TO 200
Y = X + 2.GOTO 300
100 Y =X .. 2GO TO 300
200 Y = X * (X - 1.0)300 S =Y + H
r119
Esempio 9. J4. Un programma che serva a calcolare il massimo ed il minimo tra
'tre valori dati è il seguente (cfr. esempio 9.11):
PROGRAM MAXMI2REAL MAX, MINREAD *, A, B, CIF (A.GT.B) GO TO \O
MAX=BGOTO 20
\O MAX = A20 IF (C.GT.MAX) MAX = C
IF (A.GT.B) GO TO 30MIN=AGOT040
30 MIN = B40 IF (C.LT.MIN) MIN = C
PRINT *, 'MASSIMO =', MAX, 'MINIMO =', MINSTOPEND
Dagli esempi visti risulta chiaro che, non facendo uso della struttura decisio
nale IF-THEN-ELSE, si scrivono programmi «meno facili» nel senso che la loro
comprensione è resa più difficoltosa dagli inevitabili «salti» di esecuzione.
Si osservi che il FORTRAN consente di evidenziare un punto di un programma
mediante l'istruzione costituita dalla sola parola chiave
CONTINUE
L'esecuzione di tale frase, di solito accompagnata da una etichetta, non ha altro
effetto se non quello di far proseguire sequenzialmente l'esecuzione del programma.
In mancanza del costrutto IF-THEN-ELSE è possibile realizzare la situazione di
scelta descritta in fig. 9.1 mediante le istruzioni IF-Iogico e CONTINUE nel modoseguente:
IF (c) GOTO Il)
[blocco di istruzioni 2]
GOTO n 2n) CONTINUE
[blocco di istruzioni I]
11 2 CONTINUE
Analogamente la situazione di fig. 9'.2 può essere realizzata nel modo seguente:
120
IF (c) GOTO n l
[blocco di istruzioni]
n l CONTINUE
9.7. GOTO-calcolato
Nei paragrafi precedenti si è visto come si può scegliere una tra più alternative
possibili in base al verificarsi di una condizione. Quando questa scelta è determi
nata sulla base del valore di una espressione intera si può usare l'istruzione GOTO
calcolato che in F77 ha la forma seguente:
GOTO (n l' n2, ... , nm) , espressione intera
dove:• GO TO è la parola chiave:
• n n n sono etichette non necessariamente distinte di frasi eseguibilil' 2"'" m
della stessa unità di programma cui appartiene il GOTO-calcolato;
• la virgola che precede l'espressione intera può essere omessa.Questa frase opera nel modo seguente: si calcola il valore k dell'espressione in
tera; se l ~ k ~ m l'esecuzione prosegue con l'istruzione identificata dalla eti
chetta nk
, altrimenti l'esecuzione prosegue con l'istruzione che segue il GOTO-
calcolato.In F66 l'espressione intera che compare in questa frase deve essere costituita
solo da un nome di variabile intera e non è prevista la virgola che la precede.
Inoltre in F66 non è specificato l'effetto della frase nel caso in cui il valore k
sia minore di l o maggiore di m.
Esempio 9.15. L'istruzione
GOTO (30, 40, SO), N + l - L
dà luogo ad un salto alla frase 30 se N + l - L vale l, alla frase 40 se N + l - L
vale 2, alla frase SO se N + l - L vale 3. Se il valore di N + l - L è minore di l
o maggiore di j l'esecuzione prosegue in modo sequenziale.
Esempio 9.16. L'istruzione
GOTO (7, lO, 15,7), M
provoca l'esecuzione dell'istruzione 7 se M vale 1 oppure 4, dell'istruzione lO
se M vale 2 e dell'istruzione 15 se M vale 3. Se M < l oppure M> 4 l'istruzione
GOTU-calcolato non provoca nessun salto di esecuzione.
L
121
9.8.IF-aritmetico
Questa frase ha la forma seguente:
IF (espressione aritmetica) n .. n2, n3
dove:• IF è la parola chiave:
• nl, n2, n3 sono etichette non necessariamente distinte di frasi eseguibili della
stessa unità di programma cui appartiene l'IF-aritmetico.
L'espressione aritmetica che compare in questa istruzione può essere di tipo
intero, reale o doppia precisione.
Sono quindi esempi di istruzioni IF-aritmetico i seguenti:
IF (A) 10,20,30IF (1- J) 5, 5, 3IF (8 •• 2 - 4.• A • C) 20, 60, 60IF(I+2.L)Bl,1l,Bl
L'istruzione IF-aritmetico permette di controllare l'esecuzione del programma
in base al valore dell'espressione aritmetica che vi è indicata: se il valore del
l'espressione è negativo l'effetto dell'IF-aritmetico è lo stesso di un GOTO n l ;
se il valore dell'espressione è zero l'effetto è quello di GOTO n2 mentre se il va
lore dell'espressione è positivo l'effetto coincide con quello di GOTO n3. L'istru
zione IF-aritmetico può essere quindi rappresentata nel modo descritto dalla fig.
9.10.
Figura 9.10. Diagramma a blocchi corrispondente alla istruzione IF-aritmetico.
Esercizi
9.1 Scrivere un programma che legga il valore di x e stam pi il valore s(x) dove
stx) è uguale a - l se x < O, uguale a zero se x = Oed uguale a + l se x> O.
9.9 Scrivere un programma che, dati n valori della variabile A, determini quantidi essi sono negativi, quanti positivi e quanti nulli.
9.10 Scrivere un programma che risolva lo stesso problema dell'esercizio prece
dente usando come unico strumento decisionale l'istruzione IF-Iogico.
Individuare gli eventuali errori nelle seguenti istruzioni FORTRAN:
\ ,.1 (
123
GOTO IO
lF (A.GT.B) THEN
X=X+A.By = X +.5. A
ELSE
END IF
lF (A.GT.3.1) GO TO IO
IF (A.GT.B) THEN
X=X+A.BELSE
X=A+B
y = X + 0.5. A
ENDIF
lO
IO
d)
b)
SI
116
-5, \
r -l C
a) IF (N.LT.IO) 10,20,30
30 IF (A.GT.B) THEN
IO X=X+A.B
y = X + 0.5. A
ELSE
ENDIF
20 CONTINUE
c) IF (A.GT.B) THEN
X=X+A.B
IF (X.GT.I. 7) GO TO lOELSE
X=A+B
lO Y = X + 0.5 • AENDIF
IF (N .EQ.O) IF (M.EQ.3) GOTO 515
IF (N.EQ.O.AND.M.EQ.3) GOTO 515
IF (A.LT.B.AND.GT.C) STOP
IF (A.LT.B. OR.A.GT.C) STOP
IF (A.GT.3 ..AND.A.LE.2.) A = A + B
GO TO (20, 30, 40, 50), X + 1.5
Tema data RisultatolO, 15,27 0,093,93,93 3,387, 16,87 1,3
9.8
9.4 Leggere tre interi e confrontarli. Il programma deve stampare una coppia
di interi così definita: (O, O) se i tre numeri sono distinti; (3, 3) se i tre nu
meri sono uguali; (i, j) se l'i-ma e j-rno numero sono uguali. Per esempio:
9.3 Scrivere un programma per leggere tre interi e scriverli in ordine decrescente.
Dati: a) I 2 3
b) l 3 2
c) 2 l 3
d) 2 3 I
e) 3 1 2
t) 3 2 1
9.2 Scrivere un programma che permetta di calcolare e stampare i tre valoris(x l), s(x 2) ed s(x 3) con s(x) definita nell'esercizio precedente e xl = - 2,x2 = - I, x3 = 3.
122
9.5 Scrivere un programma che legga le coordinate di tre punti nel piano: PI
=:
=: (xl' YI) , P2 =: (X 2' Y2 ) , P3 =: (X 3' Y3 ) e calcoli la distanza tra PI
e P2
e ladistanza tra PI e P3' Il programma deve stampare la maggiore tra le due distanze calcolate.
9.6 Scrivere un programma che, letti tre valori x, Y e z; permetta di verificare
se essi costituiscono le lunghezze dei tre lati di un triangolo ossia se sonopositivi e se:
X + Y> z, X + z > Y, Y + z > x.
11 risultato del programma e un numero intero uguale a:
O se x, y, z non sono lati di un triangolo;
se x, y, z sono lati di un triangolo isoscele;
2 se x, y, z sono lati di un triangolo rettangolo;
3 altrimenti.
9.7 Indicare gli eventuali errori nelle seguenti successioni di istruzioni:
lOCicli
10.1. Strutture di ripetizione
Nella stesura di un qualunque programma si presenta spesso la necessità di ese
guire più volte un gruppo di istruzioni; d'altra parte è evidente l'utilità di costrut
ti che, realizzando un procedimento ripetitivo, permettono di eseguire un certo
numero di volte, automaticamente, le stesse operazioni con dati diversi.
Esempio 10.1. Dato un cerchio di raggio r la lunghezza della circonferenza è
data da 211"r mentre l'area è data da 11"~. Per calcolare e stampare l'area e la lun
ghezza della circonferenza di 15 cerchi si procede nel modo seguente:
1. Ripeti 15 volte
1.1. leggi: r
1.2. calcola e stampa l'area
1.3. calcola e stampa la lunghezza della circonferenza
2. Stop
Esempio 10.2. Per determinare il voto medio riportato da uno studente che ha
sostenuto m esami si può seguire il seguente algoritmo nel quale s indica la
somma dei voti riportati dallo studente
1. Leggi: m2. poni s = O3. ripeti m volte
3.1. leggi un voto
3.2. aggiungi ad s il voto letto4. se m = Oallora: scrivi che lo studente non ha sostenuto esami;
vai a 5.
altrimenti: calcola il voto medio v = s/m;stampa: m e v;
vai a 5.
5. stop.
126
Il diagramma a blocchi corrispondente a questo algoritmo è quello rappresentato in fig. 10.1.
Figura 10.1. Calcolo del voto medio riportato dI uno studente che hl sostenuto m esami (cfr.esempio 10.2).
Se vogliamo calcolare i voti medi riportati da N studenti, basterà ripetere Nvolte questo algoritmo leggendo ogni volta il numero degli esami sostenuti ed ivoti riportati da ciascuno studente (cfr. fig. 10.2).
Negli esempi precedenti come in alcuni degli algoritmi del cap. l, è presenteuna struttura ripetitiva che può essere così schematizzata:
Ripeti, un numero fissato di volte.L__blocco di istruzioni
127
Tale struttura (ciclo finito) sottintende l'utilizzazione di un contatore ovvero diuna variabile il cui valore, indicando il numero di ripetizioni fatte, controlla l'e
secuzione della struttura e ne determina l'inizio e la fine. Essa viene realizzata in
ripeti N volte
Figura 10.2. Calcolo deUemedie dei voti riportati da N studenti ciascuno dei Qualiha sostenutom esami (cfr. esempio 10.2).
128
FORTRAN mediante una frase opportuna (istruzione DO) la cui esecuzione atti
va appunto un ciclo che si esaurisce dopo un numero finito di ripetizioni.Prima di descrivere dettagliatamente la frase DO è opportuno ricordare che esi
stono situazioni cicliche nelle quali si ripete l'esecuzione di determinate istruzioni
subordinatamente al verificarsi o meno di una specificata condizione. Tali strut
ture, già evidenziate nel cap. l come cicli iterativi, non sono quindi controllate da
un contatore ma da una condizione in base alla quale viene stabilito se interrom
pere o meno il ciclo. I cicli iterativi sono quindi caratterizzati dal fatto che un de
terminato blocco di istruzioni (corpo) viene eseguito ripetutamente un numero
imprecisato di volte e possono essere genericamente schematizzati in questo
modo:
Ripeti, sotto il controllo di una condizione,
L_blocco di istruzioni
dove l'esecuzione del blocco di istruzioni modifica almeno una delle variabili
che intervengono nella condizione (cfr. esempio 1.5).La fig. 10.3 mostra alcuni tipi di strutture cicliche iterative. Il primo ciclo,
indicato con la lettera (A), è detto ciclo WHILE ed è caratterizzato dal fatto che,
se la condizione non risulta vera, esso non viene mai attivato nel senso che non
vengono eseguite le istruzioni che ne costituiscono il corpo. Il ciclo contrassegnato dalla lettera (B) è detto ciclo UNTIL e presenta invece la particolarità
che il suo corpo viene sicuramente eseguito almeno una volta. Questa differenza
tra le due strutture è determinata dalla posizione dell'operazione di controllo che
si trova nel ciclo WHILE prima del blocco di istruzioni mentre nel ciclo UNTIL
è posta dopo. Il terzo tipo di struttura, contrassegnato con la lettera (C), è carat-
129
te rizzato dal fatto di avere il corpo suddiviso in due blocchi di istruzioni posti
uno prima ed uno dopo l'operazione di controllo. Evidentemente in questo caso
le istruzioni del blocco posto prima del controllo verranno eseguite sicuramente
almeno una volta mentre quelle del blocco che si trova dopo saranno eseguite
soltanto se la condizione risulta falsa.Mentre alcuni linguaggi di programmazione, come ad esempio il PASCAL,
ed alcune estensioni del FORTRAN utilizzano istruzioni particolari per realiz
zare i cicli WHILE e/o UNTIL, in F77 non è prevista alcuna istruzione di questo
tipo. E' però possibile definire un qualunque ciclo iterativo usando in modo op
portuno le istruzioni IF-logico e GOTO-incondizionato. Così il ciclo WHILE
può essere descritto mediante il costrutto:
n1
IF (.NOT. condizione) GOTO n2[blocco di istruzioni]
GOTO n1
n2 CONTINUE
il ciclo UNTIL è equivalente alla sequenza di istruzioni:
n 1 CONTINUE
[blocco di istruzioni)
IF (.NOT.condizione) GOTO n1
mentre il ciclo (C) di fig. 10.3 può essere definito nel modo seguente:
n1
CONTINUE
[blocco di istruzioni l]
IF (condizione) GOTO n2[blocco di istruzioni 2]
GOTO n1n2 CONTINUE
E' opportuno sottolineare che occorre molta attenzione nell'uso dei cicli itera
tivi come si può dedurre dall'esempio seguente.
Esempio 10.3. Si vuoi scrivere un programma che permetta di calcolare la radice
quadrata di un numero positivo x basandosi sul seguente procedimento:
lA)(8)
Figura 10.3. Alcune strutture cicliche iterative.
L
130
l. Dati due numeri positivi s e d tali che s2< x e d2> x2. poni m = (s + d)/2
3. se m2 = x allora: m è il risultato;scrivi m e vai a 4.
altrimenti: se m2 > x allora: poni d = m e torna a 2.
altrimenti: poni s = m e torna a 2.4. stop.
La fig. 10.4 rappresenta il diagramma a blocchi di questo procedimento nel
quale è presente un ciclo iterativo che sicuramente, per particolari valori di x
quali ad esempio x = 2. impone un numero infinito di ripetizioni. Questa situazione può presentarsi anche quando m = ...;; è rappresentabile con un numero
finito di cifre in quanto essa dipende dal criterio usato per controllare il ciclo.
A causa della precisione finita con cui si lavora sarà infatti difficilmente verificata
la condizione «se m2 = x» che determina la fine del procedimento. Per lo stesso
motivo sarà lecito accettare, come risultato, un valore il cui quadrato sia «quasi
uguale» ad x. tenendo presente che le richieste sulla «bontà» dell'approssimazione
non possono prescindere dalla precisione di macchina e dipendono dalle esigenze
di chi utilizza il programma. In base a queste considerazioni nel programma riportato in fig. 10.5 viene utilizzata, quale criterio di arresto, la condizione «se
Figura 10.4. Diagrammi I blecchì che descrive il procedimento per il calcolo di V; x> O(esempi. 10.3). '
131
PROGRAM RADQ XREAD *. X. S. D. SIGMA
100 CONTINUEEMME = (S + D)/2.EMME2 = EMME" 2IF (ABS(EMME2 - X). LESIGMA) GOTO 200IF (EMME2.GT.x) THEN
D= EMMEELSE
S = EMMEENDIFGOTO 100
200 CONTINUEPRINT *. 'RISULTATovOTTENUTO', EMMEPRINT *, 'ERROREvCOMMESSO', ABS(EMME - SQRT(X))STOPEND
Figura 10.5. Diagramma a blocchi e programma F77 per il calcolo di .J;, x > O.
1 m2 - x I~ o» dove o è una quantità positiva maggiore della precisione di macchina. Il valore di o viene acquisito in fase di lettura insieme a quello degli altri
dati del problema. Si osservi che un errore nella scelta della tolleranza o puògenerare ancora una ripetizione infinita delle istruzioni che costituiscono il corpodel ciclo. I criteri che vanno seguiti nella scelta di o esulano da un testo di questo
tipo e dipendono da considerazioni numeriche per le quali si rimanda, per esem
pio, a [lO].
Le osservazioni fatte sull'esempio precedente mettono m evidenza una caratteristica delle strutture cicliche iterative: esse sono semplici e di immediata com
prensione ma nascondono il pericolo che, a causa di un errore logico nel programma o di un errore sui dati, la condizione che determina la fine del ciclo
non venga mai verificata. Per evitare questo inconveniente è opportuno fissare
un numero massimo di ripetizioni in modo che la situazione ripetitiva sia con
trollata non solo dalla condizione presente nel ciclo ma anche da un contatore
che ne determina l'interruzione non appena sono state eseguite tutte le ripe
tizioni. Il ciclo iterativo viene allora inserito in un ciclo finito dando luogo ad una
struttura che può essere così schematizzata:
Ripeti, un numero fissato di volte,: Ripeti, sotto il controllo di una condizione,
~ : blocco di istruzioni.&. __1__
137
Esempio 10.8. Dati n > Oe v scrivere un programma che permetta di calcolare
e stampare la quantità
Esempio 10.7. Scrivere un programma che, dati i numeri interi n, a ed r permette
di calcolare e stampare ogni elemento della progressione aritmetica di ragione
r definito da:
I
I
ijJ.1
IIIII
II
I
k = O, l, ... , nuk = a + kr
PROGRAM UOUKINTEGER A,K,R,N,UKREAD., A, R, NDO 100 K =O.NUK = A +K. RPRINT ., K, '- MOvELEMENTO', UK
100 CONTINUESTOPEND
Si osservi che il ciclo presente in questo programma è costituito da N + l ripe
tizione del rango e che la variabile del DO è usata più volte nelle istruzioni del
rango.
n
q = Uo+ u1 + ... + un = L Ukk=O
dove Uo= v e uk
= k(k + l) uk _ l per l ..;;k ..;; n.
Un algoritmo per risolvere questo problema è il seguente:
l. Leggi: n e v
2. poni Uo = v3. poni q = v
4. ripeti n volte per k = l, 2.... , n4.1 calcola uk = k(k + i) Uo4.2 poni q = q + uk
4.3 poni Uo = uk
5. scrivi: q6. stop
)/
Infine va tenuto presente che è proibito trasferire il controllo dell'eSeCuzione. ti! dentro al rango di un DO da un punto al di fuori del rango stesso ovvero non è Ttj}-
consentito «entrare» nel rango di un DO se non attraverso l'istruzione iniziale /TDO che definisce e controlla il ciclo stesso.
r
PROGRAM VOTMEDINTEGER VOTOREAD.,MS=O.O00 27 I = l,M,
READ .,VOTOS =S +VOTO
27 CONTINUEIF (M.NE.O)THEN
VM =S/MPRINT., 'VOTOvMEDIOvSUvM =', M, 'vESAMI', VM
ELSEPRINT -. 'LOVSTUDENTEvNONvHAvSOSTENUTOvESAMI'
ENDIFSTOPEND
Esempio 10.6. Il programma seguente permette di calcolare e stampare il votomedio riportato da uno studente che ha sostenuto M esami (cfr. esempio 10.2 efig. 10.1).
Si osservi che l'istruzione DO che compare in questo programma equivale a
DO 27, I = l, M, l. L'esecuzione del ciclo inizia ponendo uguale ad l il valoredella variabile I; si calcola quindi il numero di ripetizioni imposte dal DO: se lostudente non ha sostenuto alcun esame (M = O) si ha C = O, il rango del DO viene
ignorato e l'esecuzione prosegue con l'istruzione che segue 27 CONTINUE; seinvece lo studente ha sostenuto uno o più esami vengono eseguite M volte le i
struzioni del rango ed alla fine del ciclo S contiene la somma ,!ei votLtiPortati
~Q~!!!~nt~m~n!!"e I ~~_~valo~~~±~~ .
136
Alcune regole da seguire
Affinché una struttura ripetitiva controllata dall'istruzione DO possa essere
correttamente eseguita è necessario che non si creino situazioni che impediscono
l'esecuzione sequenziale dei passi mediante i quali si realizza il ciclo-DO.~l'~~-
(9 ticolare, la variabile del DO non de~~ mai essere ridefinJ!~4!ntro il rango~~o--essa può essere usata in una qualunque istruzione del rango purché non
venga modificato il suo valore ", ~l!.Qltre, l'istruzione finale di un ciclo-DO nondeve essere un'altra istruzione DO nè un'istruzione GOTO-inco~dizioJlilto,
GOTO-assegnato, IF-aritmetico, IF(c) THEN, ELSE, ELSE IF(c) THEN, END IF,
RETURN, STOP, END. L'istruzione che viene comunemente usata come fraseterminale di un DO è l'istruzione CONTINUE che, avendo come unico effettoquello di far proseguire l'esecuzione uet programma, permette di evidenziare il
rango del DO senza intervenire operativamente nel ciclo.
138 139
ovvero:
Esempio 10.10. Scrivere un programma che, dato n ~ 5, permetta di calcolaree stampare le seguenti quantità:
DOlO I=I,NIF (I.LT.S) GOTO IOK = K + (I - 1)/2.L=L+2.1
IO M=M+I
DO IO 1= l, NIF (I.LT.5) GOTO 20K = K + (I - 1)/2.L=L+2.1
20 M =M + IIO CONTINUE
n
k = L (i - 1)/2i = 5
n
L 2i,i= 5
ti,i= I
m=
PROGRAM MLKINTEGER M, L, N, 1REAL KREAD., NM=OL=OK=O.ODO IO 1= l,N
M=M+IIF (I.LT.S) GO TO IOK = K + (I - 1)/2.L=L+2.1
IO CONTINUEPRINT., M, L, KSTOPEND
L'istruzione DO 10 I = l, N implica N ripetizioni del rango nel quale viene piùvolte utilizzata la variabile del DO. La prima istruzione del rango, M = M + I,
viene eseguita ad ogni ripetizione del rango mentre le frasi di assegnazione cheseguono l'IF-logico vengono eseguite soltanto se I ~ 5: durante le prime quattro
ripetizioni del rango risulta infatti vera la relazione I.LT.5 e l'esecuzione dell'istruzione dipendente GOTO lO provoca un salto all'istruzione finale IO CONTINUE.Lo stesso risultato del programma precedente sarebbe stato ottenuto utilizzandouno qualunque dei seguenti cicli:
READ., NM=2.N+1S = 1.0DO IO I = l, M, 2S = S.I
IO CONTINUEPRINT., 'PRODOTTOvDElvPRIMI', N + l, 'vNUMERlvNATURALlvDlSPARI', SS =0.0DO IS 1=2,M,2S = S + 1
IS CONTINUEPRINT., 'SOMMAvDElvPRIMI', N, 'vNUMERlvNATURALlvPARI', SSTOPEND
In questo programma compaiono due cicli-DO i cui ranghi sono separati nelsenso che il secondo ciclo diventa attivo soltanto quando è terminato il primo;questo ha permesso di usare lo stesso nome di variabile I nelle due istruzioni DOsenza che si creino errori o ambiguità nell'esecuzione dei due cicli. Infatti, durantel'esecuzione del ciclo controllato dall'istruzione DO lO I = l, N, 21a variabile Iassume tutti i valori dispari compresi tra l ed N secondo le regole che comandanol'esecuzione di un ciclo-DO; al momento della disattivazione del ciclo l contieneil valore N + 2 e, con l'esecuzione della frase DO 15 I = 2, N, 2 la variabile I
viene ridefinita ed il suo valore posto uguale a 2. Durante questo ciclo la variabilel assume tutti i valori pari compresi tra 2 ed N - 1 e vale N + 1 quando il ciclo
termina.
Esempio 10.9. Dato un intero positivo dispari M = 2N + I il programma seguente calcola il prodotto dei primi N + l numeri interi positivi dispari e la som
ma dei primi N numeri interi positivi pari.
Basandosi su questo algoritmo si ha:
PROGRAM SOMUKREAD.,N,VUo=vQ=VDO 20, K= l,N
UK = UO. K. (K + I)Q=Q+UKUO=UK
20 CONTINUEPRINT., QSTOPEND
Si osservi che gli elementi uk
vengono calcolati usando l'aritmetica reale per evi
tare fenomeni di overflow nel calcolo di k(k + I) con aritmetica intera.
i
!]il
140 141
Figura 10.8. Diagramma a blocchi relativo al problema dell'esempio 10.11.
Sarebbe stato però notevolmente diverso scrivere:
DOlO 1=I,NM=M +1IF (LLT.5) GOTO lOK = K + (I - 1)/2.
lO L=L+2*1
In questo caso infatti, quando I è minore di S, l'istruzione dipendente
GOTO lO impone un salto all'istruzione finale del DO che, essendo la frase di
assegnazione L = L + 2 * I, provoca la modificazione del contenuto della variabilen
L la quale, alla fine del ciclo, contiene il valore ~ 2i e non quello richiesto dalio; l
problema.
10.4. Cicli e strutture decisionali
In molti problemi l'attivazione di un ciclo-DO può essere subordinata al verificarsi o meno di una certa condizione.
Esempio 10.11. Dato un intero n> O scrivere un programma che permetta di calcolare la quantità m definita da:
n
m= [ (i+1)n se n è parii= l
n
m= [ 2in se n è disparii= l
Il programma richiesto deve realizzare il seguente procedimento:
l. Leggi: nn
2. se n è pari allora: calcola m = ~ (i + 1) n e vai a 3.i= l
naltrimenti: calcola m = ~ 2 i n e vai a 3.
io; l
3. scrivi: m
4. stop.
READ -. NEMME =0.0IF (N/2 * 2.EQ.N) THEN
DO 150 I = l, NEMME = EMME + (I + 1.0) * N
150 CONTINUEELSE
DO 200 I = l, NEMME = EMME + 2. * I * N
200 CONTINUEENDIFPRINT *,'N =', N, 'vM =', EMMESTOPEND
F v
J
Una descrizione più dettagliata di questo algoritmo (cfr. fig. 10.8) mette in
evidenza la necessità di usare due strutture cicliche alternative la cui attivazioneè determinata dalla condizione «se n è pari».
Facendo uso della struttura decisionale IF-THEN-ELSE possiamo quindi scnvere il programma seguente:
E' importante osservare che quando un ciclo-DO fa parte del blocco di istruzioni che seguono una delle frasi IF (c) THEN, ELSE IF (c) THEN, ELSE, il
rango del DO deve essere interamente contenuto nel blocco che contiene la fraseiniziale del ciclo ossia l'lstruzione DO.
-_...:---'/;(
142
D'altra parte, se /'istruzione IF (c) THEN compare dentro il rango di un ci
c/o-DO anche la corrispondente istruzione END IF deve far parte del rango.
Esempio 10.12. Supponendo di aver intervistato N pers~ne di se.sso diverso s~
vuoI calcolare l'età media dei maschi e quella delle femmine. I dati sono raccolti
in N schede ciascuna delle quali contiene l'età ed un codice che indica il sesso del-
l'intervistato (O per le femmine ed I per i maschi). .Indichiamo con Nm (NO il numero totale dei maschi (delle femmine) e con
Em (ED la somma delle loro età; il problema può essere allora risolto come segue:
I. Leggi: N
2. poni Nm = Oed Nf = O
3. poni Em = Oed Ef = O
4. ripeti N volte:
4.1. leggi una coppia di dati
4.2. se codice = 1 allora: aggiungi una unità ad Nm eaggiungi l'età ad Em. Vai a 4.3.
altrimenti: aggiungi una unità ad Nf e
aggiungi l'età ad Ef. Vai a 4.3.
4.3. continua il procedimento ripetitivo5. calcola e stampa l'età media dei maschi e quella delle femmine
6. stop.
11 programma richiesto può essere allora il seguente:PROGRAM ETAMEDINTEGER CODICE,ANNIREAD -. NNM=ONF=OEM =0.0EF =0.0DO 151 NUM= l,NREAD *, ANNI,CODICEIF (CODlCE.EQ.1) THEN
NM=NM+IEM =EM + ANNI
ELSENF = NF + 1EF =EF + ANNI
END IF151 CONTINUE
ETAM = EM/NMETAF = EF/NF ,PRINT * 'NUMERO'lDEI'lMASCHI', NM,''lETA'' MEDIA, ETAMPRINT *: 'NUMERO'lDELLE'lFEMMINE', NF, 'v ETA" MEDIA', ETAFSTOPEND
143
10.5. Trasferimento ad istruzioni fuori del rango
La ripetizione delle operazioni indicate dalle istruzioni del rango di un DO può
essere interrotta trasferendo il controllo dell'esecuzione dall'interno del rango ad
una istruzione che, pUT facendo parte della stessa unità di programma. non appar
tiene al rango. In questo caso la variabile del DO mantiene, al momento dell'uscitadal ciclo, il valore definito durante l'ultima ripetizione.
Esempio 10.13. Dato N, si vogliono leggere al più N valori della variahile PESO;
la lettura dei dati deve terminare con il primo valore negativo o nullo della variabile. Scrivere un programma che segnali se tutti gli N valori di PESO sono positivi e, in ogni caso, fornisca il numero di valori letti.
Seguendo lo schema indicato in fig. 10.9 si ha:
READ *, NDOIO,K=I,N
READ *, PESOIF (PESO.LE.O.O) GO TO 25
IO CONTINUEPRINT *, 'TUTTIvI vVALORIvSONOvPOSITIVI'K=N
25 PRINT *, 'NUMEROvDlvVALORIvLETTI', KSTOPEND
Figura 10.9.
144
Dopo aver acquisito il valore di N inizia il ciclo controllato dall'istruzioneDO l O, K = l, N; essa impone N ripetizioni del rango che è costituito da dueoperazioni: una di lettura ed una di controllo. Se tutti i valori della variabilePESO risultano positivi l'istruzione dipendente GOTO 2S non viene mai eseguita ed il ciclo si esaurisce dopo N ripetizioni del rango. L'esecuzione prosegue
allora in modo sequenziale con l'istruzione che segue la frase terminale del DO.Siccome il ciclo è stato completamente eseguito, al momento della sua disattiva
zione la variabile K contiene il valore N + l: da qui la necessità di inserire l'istru
zione K = N prima della stampa del numero di dati letti. Nel caso in cui i valoridella variabile PESO non siano tutti positivi il ciclo viene interrotto non appena
si trova un valore negativo o nullo: in questo caso infatti l'esecuzione dell'istru
zione dipendente GOTO 2S impone un salto nell'esecuzione al di fuori del rango
del DO che provoca l'immediata disattivazione del ciclo e l'esecuzione dell'istru
zione individuata dalla etichetta 2S. Siccome il ciclo non è stato completato il
valore di K è quello definito durante l'ultima ripetizione e fornisce quindi il nu
mero di valori letti: i primi K - l sono tutti positivi mentre il K-mo, essendo nega
tivo o nullo, ha provocato l'interruzione delle operazioni di lettura.
Esempio 10.14. Il seguente programma permette di calcolare la radice quadratadi un numero positivo x mediante l'algoritmo UI fig. 10.6: \
PROGRAM RADICEREAD -. X, SIGMA, N, S, DDO 100 1= 1, N
EMME= (S + D)/2.EMME2 = EMME •• 2IF (ABS(EMME2 - X).LE.SIGMA) GOTO 200IF (EMME2.GT.x) THEN
D=EMMEELSE
S= EMMEEND IF
100 CONTINUEPRINT., 'E" STATOvESEGUITOvILvNUMEROVMASSlMOvDl',
• 'vRlPETIZI0NI'STOP
200 PRINT., 'SONOVSTATEvESEGUITE,I, 'vRIPETIZI0N(PRlNT .,'E" STATOvTROVATOvlLvRISULTATO', EMMEPRINT., 'CONvUNvERRORE: ABS (EMME - SQRT(X»STOPEND
145
10.6. Cicli-DO annidati
Come mostra il diagramma di fig. 10.2, possono presentarsi situazioni che prevedono due o più cicli finiti uno dentro l'altro (annidati). Il linguaggio F77 prevede
la possibilità di a.ttivare, all'interno del.ran...g..o di u. n.. DO.. '. altri Cicli-D.O. con. l'.unica */:limitazione che il Jl111KiLdeldçJQ l!i'1 interno deve essere interamente contenutodentro al rango'del ciclo più esterno. V~ì~'~-p-~na--èii osservare 'che~ slc~~~;~~
vanabiI~~DO ~~;:;d~~ ~ai essere ridefinita dalle istruzioni del rango, le
istruzi~!.QQEhe _(;~!!!roll~I!.Q.gçti.fif1iti annidati devono usare variabili di nome - .~/,<!ive!S.-2' Non sono previste limitazioni sul numero di cicli-DO che possono essereannidati.
Esempio 10.15. Il seguente programma permette di calcolare e stampare il votomedio di N studenti (cfr. fig. 10.2):
PROGRAM MEDIE1INTEGER VOTOREAD., ND030 NS= l,N
PRINT -. 'STUDENTEvNUMERO', NSREAD .,MS=O.ODO 15 1= 1, M
READ., VOTOS=S+VOTO
15 CONTINUEIF (M.NE.O) THEN
VM = S/MPRINT., 'VOTOvMEDlOvSUvM =', M, 'v ESAMI', VM
ELSEPRINT -. 'LOvSTUDENTEvNONvHAvSOSTENUTOvESAMI'
END IF30 CONTINUE
STOPEND
Più strutture cicliche annidate possono utilizzare la stessa frase terminaI=. che,
in questo'caso, deve essere considerata come appartenente soltanto al rango ~e~
DO più interno.
Esempio 10.16. La successione di istruzioni:
N=ODO 50 M = 1,5K=MDO 50 J = O, 3
L= J50 N = N + l
146
equivale alla seguente:
N=ODO 100 M=I,5K=MDO SO J = O, 3L=J
SO N =N + l100 CONTINUE
Dopo l'esecuzione la variabile M vale 6, K vale 5, J vale 4, L vale 3 ed N vale20. Il rango del DO più interno, controllato dalla variabile J, viene ripetuto
20 volte mentre quello del DO più esterno che utilizza la variabile M, viene ese
guito 5 volte.Anche se è previsto che due o più cicli-DO annidati si chiudano sulla stessa
frase può essere utile evidenziare il rango di ciascun ciclo mediante istruzioni
CONTINUE distinte.
Esempio 10.17. La successione di istruzioni:
N=OL=ODO lO 1=1,2
N=N+ lDO lO J=I,3
K=J + NDO lO M = 1,3
lO L=L+K
equivale alla seguente:
N=OL=ODO lO I = 1,2
N=N+ lDO 20 J = 1,3
K=J +NDO 30 M = 1,3
L=L+K30 CONTINUE20 CONTINUElO CONTINUE
Il rango del DO più esterno, controllato dalla variabile I viene eseguito 2 volte;
quello del DO intermedio, controllato da J, viene eseguito 6 volte mentre quello
del DO più interno, controllato dalla variabile M, viene eseguito 18 volte. Dopo
l'esecuzione delle istruzioni indicate le variabili I, J ed M contengono rispettivamente i valori 3, 4 e 4 mentre N contiene il valore 2, K il valore 5 ed L il valore 63.
..• _-----------
147
L'abitudine di separare i ranghi di cicli-DO annidati mediante istruzioni finali
distinte non è utile soltanto per aumentare la leggibilità di un programma ma 'ianche per evitare errori quando nel rango di uno dei cicli annidati vengono esegui- "te operazioni di controllo. Tali operazioni non devono infatti prevedere un tra- '
sferimento ad una istruzione che appartenga al rango di altri cicli interni; in parti
colare è sbagliato trasferire il controllo dell'esecuzione del rango di un DO allafrase finale di un'altro ciclo in esso annidato.
Esempio 10.18. Il seguente gruppo di istruzioni
L=ODO lO M = 1,5
L=L+MIF (M.LE.3) GOTO lODO 20 K = 1,3
20 L = L + (M - K)IO CONTINUE
corrisponde al diagramma a blocchi di fig. 10.10; il rango del DO più esterno,
controllato dalla variabile M, viene eseguito cinque volte mentre il ciclo più interno viene attivato soltanto se M è maggiore di 3. Alla fine dell'esecuzione deidue cicli i contenuti delle variabili M, L e K sono rispettivamente 6, 4 e 30. La
distinzione mediante etichette diverse delle frasi terminali dei due cicli è neces-
ripeti per m = 1,2,3,4,5
v
Figura 10.1O. I cicli finiti annidati esaminati nell'esempio 10.18.
148 149
10.3 Indicare gli eventuali errori nei seguenti gruppi di istruzioni:
c) DO lO K = l, lO
L=KIF (K.GT.5) GOTO lOL = K + 3 l''{ U
lO IF (L.LE.LM) K = L - 2
d) GO TO 5
DO lO I = l, 100
5 H = 0.5. I
A=I·H+AlO CONTINUE
saria per effettuare in modo corretto il trasferimento previsto nel rango del DO
più esterno. Sarebbe stato infatti sbagliato scrivere, per esempio, la successione di
istruzioni:
L=ODO lO M=1,5
L=L+MIF (M.LE.3) GOTO lODO lO K=I,3
lO L=L+(M-K)
in quanto l'istruzione dipendente GOTO lO trasferisce il controllo dell'esecu
zione alla frase finale del ciclo più interno.
a) DO lO 1M1 = 1, 5
IMI = IMI + 3
lO CONTINUE
b) DO 5 K = N + 1, J, L5 IF(K.LE.MAN) IS = N • K
l'I V
\ .
Esercizi
10.1 Alcune delle istruzioni seguenti sono sbagliate. Perché?
10.2 Determinare il numero di ripetizioni del rango per ognuna delle seguenti
istruzioni:
DO 22 l = 22, 77, - 1DO 37 \JM-l= 1, 10,2 SCk (16
DO N, 1= 1, 10,2 rlODO lO, K = L - 3, J + 2, 3 - LI
DO 1 JS = 0.0, 8.0, 0.5 l'IO
DO 3 S = 0.0, 8.0, 0.5
DO 83 K = L + M, KDO 5 M = L, lO, LDO 21, ITER = LO, A + B,:,1.l
\
! l
f) DO lO l = 20, l, - l
Al = 1./2.
DO 20 K = l, l i I (lO L=K+3
20 CONTINUE
(a) DO lO l = 1,4 (b) S = O.S = O. DO lO l = 1,4S=S+I S=S+I
lO CONTINUE lO CONTINUE I
(c) S = O. (d) S = l.DO lO l = 4, l, - 1 DO lO l = 1,4S = S + 1./1 S = S • l
lO CONTINUE lO CONTINUE
e) IF (A - B.LE.E) THEN
DO lO I = l, N
X=X+HPRINT., X •• 2
ELSE
X=X-H
PRINT.,2. X
lO CONTINUE
END IF
10.4 Indicare il contenuto della variabile S dopo l'esecuzione delle sequenze diistruzioni (a), (b), (c), e (d) seguenti:
10.5 Scrivere un programma che, assegnate n ~ l teme di numeri interi, esegua
per ciascuna di esse quanto previsto nell'esercizio 9.4.
10.6 Scrivere un programma che, assegnate n ~ l teme di numeri reali, permetta
di stabilire per ciascuna di esse se i valori letti costituiscono i lati di untriangolo (cfr. esercizio 9.6).ì
c:
DO 3, 1= 8, 8DO 7 M = 1, 55, 1ODO lO J = lO, O, - 1 (f
DO 2, L = O,30 I
DO 6 K = 0.1, 3.5, 2.1
150
10.7 Scrivere un programma che, assegnato un numero intero positiv~ N, s~am~i. l h 2 r ~ N < 2r + l e le cifre della rappresentazione binariaIl valore r ta e c e ...."di N. (cfr. §3.l).
10.8 Scrivere un programma che permetta di stampare il valore che un polinomion .
. ., d -- l () - 1: a Xl assume per x = z asse-.a coefficienti reah di gra o n? 'Pn X - j= O i
gnato (l dati del problema sono: n, z ed i coefficienti ao' al' ..., an)·
[IlLe variabili dimensionate
11.1. Introduzione
Nel corso dei precedenti capitoli si è sempre associato un nome simbolico aduna singola locazione di memoria. In FORTRAN è possibile anche individuare
con un nome simbolico un insieme ordinato di locazioni consecutive atte a contenere dati tutti del medesimo tipo. Un tale insieme viene detto variabile dimensiona!a (array) e le locazioni che lo costituiscono sono dette elementi della variabile dimensionata; ogni elemento può essere individuato specificandone in modo
opportuno la posizione tramite degli indici. In pratica, è possibile tradurre in
FORTRAN la notazione vettoriale comunemente usata, ad esempio, nella descrizione di molti problemi e algoritmi di natura scientifica; tale possibilità si rivelatalvolta indispensabile per il trattamento di insiemi di valori omogenei.
Esempio Il. ( Consideriamo l'algoritmo descritto nell'esempio 10.8. In tale algo
ritmo si fa uso della notazione vettoriale che permette una descrizione sintetica e
compatta delle operazioni da svolgere. In particolare al passo 4.1 si descrive il cal
colo di uk ' ossia di u 1 se k = l, u2 se k = 2, e così via; i nomi uO
' u1
' ... un siriferiscono a entità fra loro distinte. Nel programma SOMUK non si fa corrispon
dere una cella di memoria ad ognuno dei valori ul' ... , un' in quanto il nomesimbolico UK identifica sempre la stessa cella dove, al variare di K durante l'esecuzione del ciclo-DO, viene memorizzato ogni volta un valore diverso.
Supponiamo ora di voler scrivere un programma che, calcolati uO
' u1' ..., un'
stampi la somma degli elementi di posto dispari ul. u
3... e quella degli elementi
di posto pari uO' u2 ' ..• Se il valore di n è fissato, ad esempio n = 7, si può ottenere lo scopo desiderato con il seguente programma:
152
READ., VUO=VUl = 2.• UOU2 = 2.• 3.• UlU3 = 3.• 4 .• U2U4 = 4.• S.• U3US = 5.• 6.• U4U6 = 6.• 7.• USU7 = 7.• 8.• U6SP = UO + U2 + U4 + U6SD= Ul + U3 + US + U7PRINT. 'SOMMA DEGU ELEMENTI DI POSTO PARI =', SPPRINT.: 'SOMMA DEGU ELEMENTI DI POSTO DISPARI =', SD
STOPEND
E' evidente che per valori grandi di n è molto scomodo scrivere un programma
analogo al precedente. Utilizzando invece una variabile dimensionata i cui ele
menti contengano i valori uO
' u1' ... , un è possibile scrivere un programma che
risolve il problema qualunque sia n (cfr. esempio 11.10).
Esempio 11.2. Sono noti i voti conseguiti da 200 studenti di un corso di laurea
che prevede 30 esami. Per poter facilmente trattare questo insieme di dati si può
costruire una tabella rettangolare A di 200 colonne e 30 righe: in ogni colonna
si riportano i voti conseguiti da uno studente. La tabella A risulta così costituita
da 6000 dati: il voto conseguito dal j-esimo studente all'i-esimo esame si trova
all'incrocio fra la j-esima colonna e l'i-esima riga; esso è quindi individuato dalla
coppia di indici (i, j) e può essere indicato con il simbolo aj,j'
Nel seguito useremo il termine vettore per indicare un insieme di dati ognuno
dei quali è individuato da un solo indice (cfr. esempio 11.1) e il termine ma~ric~per indicare un insieme di dati ognuno dei quali è individuato da una coppia, di
indici (cfr. esempio 11.2). Un vettore è una tabella unidimensionale e una matnce
è una tabella bidimensionale; si possono costruire anche tabelle a tre o più dimen
sioni, per poter trattare insiemi di dati particolari quali, ad esempio, il numero di
persone che abitano ad ogni piano ad ogni numero civico di ogni strada in una cit~ta, oppure i valori che una funzione di tre o più variabili assume su un reticolo di
punti. Ad una tabella, intesa come insieme di dati individuabili tramite indici,
si può far corrispondere in FORTRAN una variabile dimensionata.
153
Il.2. Nomi di variabili dimensionate e istruzione DIMENSION
Perché un nome simbolico possa essere considerato in una unità di programma
come nome di una variabile dimensionata, occorre che di ciò sia informato il com-~nj!atore:>al quale devono essere fomite, in particolar~-,-i;seg~~~ti indica;~~i:
• il tipo della variabile, ossia il tipo comune a tutti i suoi elementi; -
• il numero di dimensioni;• l'ampiezza di ogni dimensione.
Ad esempio, se si vuoi definire una variabile dimensionata corrispondente ad
una matrice di 30 righe e 200 colonne con elementi reali, si deve specificare
al compilatore che la variabile è di tipo reale e che ha due dimensioni, la prima di
ampiezza 30 e la seconda di ampiezza 200.
Le indicazioni suddette, insieme ad altre che verranno esaminate in seguito,
devono essere specificate tramite un dichiaratore di variabiledimensionata che ha
la forma:
dove:
• v è un nome simbolico che costituisce il nome della variabile dimensionata; iltipo della variabile è il tipo (esplicito o implicito) di v;
• n è il numero di dimensioni, e deve essere minore o uguale di 7 (in F66 deve
essere n ~ 3);
• dI" .. , dn sono i dichiaratori di dimensione. Per ogni valore di i, d ha la formaI
infj : SUPj
dove infj e SUPj sono la limitazione inferiore e la limitazione superiore per l'i
esima dimensione. ~~~e ch~ v ha dimensioni costanti quando, per ogni i, inf. '" _. . . l
e SUPj sOIl~ espresslOnl aritmetiche ottenute combinando costanti e nomi di'oca-
stanti inte~~L~tre forme per infj e sUPi' consentite soltanto all'interno di sottoprogrammi, verranno esaminate nel cap. 15. In ogni caso il valore di sup. deve
essere maggiore o uguale di quello di infj; se infj è uguale a l, il dichiaratore d.
può assumere la forma (unica consentita in F66) I
suP;
L'ampiezza dell'i-esima dimensione è data da
Sj = sUPi - infj + l
e l'ampiezza di v, ossia il numero totale dei suoi elementi, è il prodotto delle. n
ampiezze s., ovvero è data da n s..I i=l I
154
Esempio JJ.3. Nel dichiaratore di variabile dimensionata
T
155
Esempio 11.6. Le frasi
A (IO, 20)
si ha: n = 2, infl
= inf2 = l, sUPI = lO, sUP2 = 20; l'ampiezza della prima dimen
sione è quindi s = lO, quella della seconda è s2 = 20, da cui segue che l'ampiezza
della variabile 1è SI x s2 = 200. Osserviamo che il dichiaratore usato è equiva-
lente ad uno qualunque dei seguenti:
A(I : 10,20) A(I : lO, l : 20) A(lO, l : 20)
PARAMETER (N = IO)REAL A(N, N + I), V(N), U(N)
definiscono la matrice reale A di lO righe e Il colonne e i vettori reali V ed U di
ampiezza lO. Notiamo che nei dichiaratori di dimensione compare il nome sim
bolico N che non è un nome di variabile, bensì un nome di costante definito nella
precedente frase PARAMETER. Le due istruzioni sono pertanto equivalentialla frase
Nel seguito useremo abitualmente, per le variabili a una e due dimensioni,
la terminologia seguente: «vettore di lunghezza SI» in luogo di «variabile a una
dimensione di ampiezza SI»; «matrice di SI righe e s2 colonne», o «matrice
s x s », in luogo di «variabile a due dimensioni di ampiezze rispettive SI e s2 »;l 2 . .. b
«matrice quadrata di ordine n» in luogo di «variabile a due dimensioni entram e
di ampiezza n». Il significato di altre locuzioni usate in luogo delle precedenti
sarà facilmente deducibile da queste.
Un dichiaratore di variabile dimensionata può comparire in una frase dichia
rativa di tipo, come negli esempi che seguono:
Esempio JJ.4. La frase
INTEGER N, M(60), VOTI (15,20)
indica al compilatore che N, M, VOTI sono variabili di tipo intero, e le ultime due
sono variabili dimensionate. In particolare M è un vettore di 60 elementi e VOTI
è una matrice di 15 righe e 20 colonne.
Esempio JJ.5. La frase
REAL L(lO), A(- 5 : 4), U(O : 20), Z(l : 5, 6), W(l, 3,4)
specifica che L, A, U, Z, W sono variabili dimensionate di tipo reale; in particolare
L è un vettore di lO - l + l = IO elementi;
A è un vettore di 4 - (- 5) + l = lO elementi;
U è un vettore di 20 - O + l = 11 elementi;
Z è una matrice di 5 - l + l = 4 righe e 6 - l + l = 6 colonne;
W è una variabile a tre dimensioni di ampiezze rispettive:
2 - l + l = l, 3 - l + l = 3 e 4 - l + l = 4.Osserviamo che L ed A hanno la stessa ampiezza, pur essendo diversi i loro dichia-
ratori di dimensione.
REAL A(lO, Il), V(lO), U(lO)
L'istruzione DIMENSION
Se si vuoI dichiarare che uno o più nomi sim bolici sono nomi di variabile di
mensionata si può usare l'istruzione dichiarativa DIMENSION, la cui forma generale è:
DIMENSION lista
dove:
• DIMENSION è la parola chiave che identifica la frase;
• lista è una lista di dichiaratori di variabile dimensionata.
La presenza di un dichiaratore di variabile dimensionata in una frase DIMENSION
non ha alcun effetto riguardo al tipo della variabile stessa. A tal proposito occorre
osservare che una frase DIMENSION può precedere o seguire eventuali frasi di
specificazione di tipo in cui compaiano nomi di variabili dimensionate da essa
dichiarate. In ogni caso un dichiaratore di variabile dimensionata non può comparire in più frasi dichiarative nella stessa unità di programma.
Esempio 11. 7. L'istruzione
REAL MAT (5, io. O : l)
è equivalente a una qualunque delle coppie di istruzioni seguenti:
REAL MATDIMENSION MAT(5, IO, O: 2)
DIMENSION MAT(5, IO, O: 2)REAL MAT
E' invece sbagliata la presenza nella stessa unità di programma delle due istruzioni seguenti:
l:
156
REAL MAT (5, lO, O: 2)DIMENSION MAT (5,10, O: 2)
Va notato che spesso si preferisce evitare l'uso dell'istruzione DIMENSION
e inserire i dichiaratori delle variabili dimensionate in frasi di specificazione di \ I
tipo; si veda a tale proposito quanto è stato detto nel cap. 5 circa l'opportunità !di dichiarare esplicitamente il tipo di tutte le variabili in ogni unità di program
ma.
11.3. Nomi di elementi di variabile dimensionata
Un elemento di variabile dimensionata è identificato da un nome della forma
dove:
• v è il nome della variabile dimensionata;
• n è uguale al numero delle dimensioni di v;
• e l , . · . , en sono espressioni intere, dette espressioni indice, che possono conte
nere a loro volta riferimenti a elementi di variabile dimensionata (anche di v stes
sa). In F66 le espressioni indice potevano avere soltanto una delle forme seguenti
j * s + k, j * s, s ± k, s, k
dove j e k sono costanti intere, e s è una variabile intera.Il simbolo (el' ... ,en) è detto indice dell'elemento; nel seguito useremo tal
volta il termine «inuice» in luogo di «espressione indice» quando non vi sia ambiguità.
Esempio 11.8. Date le variabili dimensionate IPIV, A, Z, W dichiarate con la frase
DIMENSION IPIV (IO), A(5, 6), Z(lO, IO, lO), W(O : lO)
sono sin tatticamente corretti i seguenti nomi di elementi:
IPIV (IO)IPIV (3. J)IPIV (IPIV(I)A(I, J)A(I •• 2,1)A(I, IPIV(K»Z(I + 2, I + 1,5)W(K)W(I+(J-I).N)
157
Sono invece sbagliati i nomi A(I) e IPIV(X): il primo perché contiene una sola
espressione indice mentre A è una variabile a due dimensioni, il secondo perché
X è un'espressione che non può essere usata come espressione indice. ( r • ',. I "/,. 7 Il
Il nome di un elemento di variabile dimensionata può essere usato come unnome di variabile ordinaria in una espressione. nella lista di una frase di ingresso/uscita, e in una frase di assegnazione alla sinistra del segno =. Occorre co
munque tener presente che, al momento dell'esecuzione dell'istruzione in cui
esso compare, il valore di ogni espressione indice deve essere compreso fra lalimitazione inferiore e la limitazione superiore della dimensione corrispondente.Così nell'esempio 11.8, i riferimenti a W(K) ed A(I, J) sono corretti soltanto
se è O~ K ~ lO, l ~ I ~ 5 e I ~ J ~ 6.
Esempio 11.9. Date le variabili IND e A dichiarate con la frase
INTEGER IND (5), A(O : 5,6)
supponiamo di eseguire le seguenti istruzioni
DO 15 1=1,5IND (I) = I +1PRINT., A(lND(I), I - l)
15 CONTINUE
Mentre la prima istruzione del rango del DO viene sempre eseguita correttamente,
la seconda provoca una situazione di errore per I = l e 1= 5. Infatti per I = l la
seconda espressione indice I - l, assume il valore zero che non è compreso fra le
limitazioni inferiore e superiore della seconda dimensione di A. Analogamente,
per I = 5 la prima espressione indice IND(I) ha il valore non consentito 6.
Esempio 11.10. Si vuole scrivere un programma che, da ti n >O e v, permetta di
calcolare uk = k(k + l) uk _ l' per k = l, ... , n con Uo= v. Si vuole inoltre cal
colare e stampare la somma dei valori uk con k dispari e quella dei valori uk con
k pari (cfr. esempio 11.1).
Per poter specificare l'ampiezza della variabile dimensionata U i cui elementi
contengono i valori uo' ul' ... , un occorre fissare una limitazione superiore per n.Il seguente programma, SOMUKV, risolve il problema per n ~ 50.
158 159
TBAMB contiene il numero di bambini, maschi e femmine. nati negli anni dal
1980 al 1985.
Nel programma ora scritto è evidente l'utilità di poter usare per la matrice
TOT indici di riga e di colonna variabili rispettivamente fra O e I e fra 1980 e
1985. Se infatti avessimo usato il dichiaratore, consentito anche in F66,
TOT (2, 6)
PARAMETER (LINF = 1980, LSUP = 1985)INTEGER TOT (0:1, LINF : LSUP), SEX, ANNO, NOK, TBAMBREA D -. N
C AZZERAMENTO DEI TOTALINOK=OTBAMB =0DO 100 ANNO = LINF, LSUPDO 100 SEX = 0,1TOT (SEX, ANNO) = O
100 CONTINUEC CICLO: SI LEGGE UNA COPPIA DI DATI PER VOLTA.C SE NON E' VALIDA SI PROCEDE ALLAC LETTURA SUCCESSIVA,C ALTRIMENTI SI AGGIORNA NOK, E EVENTUALMENTE,C TBAMB E TOT (SEX, ANNO)
DO 200 I = l, NREAD -. SEX, ANNOIF (SEX.NE.O.AND.SEX.NE.l) GOTO 200NOK= NOK + lIF (ANNO.LT.LINF.OR.ANNO.GT.LSUP) GOTO 200TBAMB = TBAMB + lTOT (SEX, ANNO) = TOT (SEX, ANNO) + l
200 CONTINUEC STAMPA DEI TOTALI
PRINT ., 'NUMERO DI COPPIE VALIDE:'. NOKIF (NQ!<..NE.O) THEN
PRINT., 'TOTALE BAMBINI NATI FRA IL', LSUP,':', TBAMBPRINT ., ..... MASCHI .....
DO 300 ANNO = L1NF, LSUPPRINT -. •ANNO', ANNO, ':', TOT (O, ANNO)
300 CONTINUEPRINT ., '.... FEMMINE .....
DO 400 ANNO = L1NF, LSUPPRINT ., •ANNO', ANNO, ': TOT (l, ANNO)
400 CONTINUEELSEENDIFSTOPEND
Osserviamo che per evitare riferimenti a elementi U(K) con K > 50 si è inserito
nel programma un controllo sul dato in ingresso N; se N > 50 il programma termina subito con un messaggio di avvertimento.
PROGRAM SOMUKVPARAMETER (NMAX = 50)DlMENSION U(O : NMAX)READ., N, VIF (N.GT.NMAX) GOTO 50
C CALCOLO DI U(K), K = O, l, ... , NU(O) = VDO 25 K = l, NU(K) = U(K - l) • K • (K + l)CONTINUE
CALCOLO DELLA SOMMA DEGLI U(K), CON K DISPARISD=O.0035K= I,N,2SD = SD + U(K)CONTINUE
CALCOLO DELLA SOMMA DEGLI U(K), CON K PARISP= O.00 45 K = O, N, 2SP = SP + U(K)
45 CONTINUEC STAMPA DEI RISULTATI
PRINT ., 'SD =', SD, 'SP =', SPSTOP
50 CONTINUEPRINT., 'N DATO TROPPO GRANDE: NMAX =', NMAXSTOPEND
Esempio 11.11. Si vuoI sapere quanti bambini sono nati negli anni dal 1980 al1985 in una comunità costituita da N persone; si vuole inoltre costruire una ta
bella da cui risulti quanti fra i bambini suddetti sono maschi e quanti femmine.Il programma seguente risolve il problema. A tale scopo si legge, per ogni per
sona appartenente alla comunità, una coppia di dati costituita da: sesso (codi
ficato come O se maschio e l se femmina) ed anno di nascita. I totali desiderativengono memorizzati nella matrice TOT di due righe, una per ogni sesso, e sei colonne, una per ogni anno dal 1980 al 1985: gli indici di riga possono assumere i valori O e l, e gli indici di colonna variano fra 1980 e 1985. Osserviamo che, per ga
rantire la corretta esecuzione del programma, si controlla ogni coppia di dati cheviene letta: una coppia non è considerata valida se il suo primo elemento non èzero oppure uno. Al termine dell'esecuzione del ciclo controllato dall'istruzione
DO 200 I = l, N la variabile NOK contiene il numero di coppie di dati valide e
25C
·1 35i ~i':
C
160 161
in cui si mettono in evidenza soltanto il numero di righe e il numero di colonne,
avremmo dovuto far variare gli indici di riga fra 1 e 2 e quelli di colonna fra 1 e 6;
così, in corrispondenza alla coppia di dati SEX e ANNO avremmo dovuto far
riferimento all'elemento
TOT (SEX + 1, ANNO - LINF + 1)
anziché, come si è fatto, all'elemento
Esempio 11.12. Siano dati i vettori di ampiezza s = IO
INTEGER LISTA uo), COPIA (- 5 : 4)
11 primo elemento di LISTA è LISTA (1), il secondo è LISTA (2), e così via
fino al decimo che è LISTA (l O); invece, nel vettore COPIA la prima posizione
spetta all'elemento COPIA (- 5), la seconda a COPIA (- 4), e la decima e ultimaa COPIA (4).
TOT (SEX, ANNO).
\J ~ [> I ~ I \/1 ~ Ivi 1'/" ( / i '
IlA. Disposizione in memoria degli elementi di una variabile dimensionata
Ad ogni elemento di una variabile dimensionata di ampiezza s corrisponde un
numero fra l ed s che rappresenta la sua posizione in memoria all'interno dell'insieme di locazioni consecutive identificato dal nome della variabile. La posi
zione di un elemento dipende dal numero di dimensioni della variabile, dai valori
delle espressioni indice e dai dichiaratori di dimensione, secondo lo schema ri
portato in fig. Il.1, dove il simbolo i" indica il valore della k-esima espressione
indice e".
Dalla fig. Il.1 si deduce anche che ~~E1atrici sono «memorizzate per colonne»,
in quanto in memoria tutti gli elementi della-'pri~~-cofonna,ordinati per valorr
crescenti dell'indice di riga, precedono gli elementi della seconda colonna, ordinati
allo stesso modo, e così fino all'ultima colonna.
In generale, gli elementi di una variabile di n dimensioni sono ordinati nel modo
seguente: l'n-esimo indice In varia da infn a sUPn; per ogni varore di in l'indice
in_ 1 varia da infn_ 1 a sUPn_l; per ogni coppia di valori di in e in_ 1 l'indice
in- 2 varia da infn_ 2 a sUPn_2; così via fino a il che varia da infl a sUPI per ogni
insieme di valori di in' in_I' ... , i2 .
Esempio 11.13. Le matrici A e 8 dichiarate con la frase
Figura Il.1. Ordinamento degli elementi di variabile dimensionata.
DlMENSION H(2, 2, 2)
DIMENSION A(2, 3), 8(3,2)
hanno ambedue ampiezza 6. A ha due righe e tre colonne e i suoi elementi sono
ordinati nel modo descritto in fig. I l.2; 8 ha tre righe e due colonne ed è memo
rizzata per colonne come si vede in fig. Il.2.
L'ordinamento degli elementi della variabile dichiarata da
è infine descritto in fig. 11.3, da CUI si vede che tutti gli elementi il cui terzo
indice i3
vale 1 precedono tutti quelli per i quali i3 vale 2, ossia che H è «rnemo
rizzata per piani».
In fig. IlA si visualizza tramite le frecce l'ordine in cui sono memorizza ti gli
elementi di A, 8 e H; in questa figura si evidenzia la memorizzazione per colonne
di A e 8 e per piani di H.
Lo schema riportato in fig. Il.1 è valido per n ~ 3 anche in F66. A questo pro
posito osserviamo che secondo tale versione del FORTRAN è consentito che il
valore di una espressione indice nel nome di un elemento di variabile dimensionata
superi la limitazione superiore della corrispondente dimensione, purchè la posizio
ne dell'elemento, calcolata secondo lo schema di fig. Il.1 ,non superi l'ampiezza
totale della variabile; così, per esempio, se le dimensioni della matrice MAT sono
specificate dalla frase
posizione
l + (il - infl)l + (il - infl) + (i2 - inf2) * SI
l + (il - infl) + (i2 - inf2) * SI++ (i3 - inf3) * SI * s2
l + (il - infl) + (i2 - inf2) * SI++ (i 3 - inf3) * SI * s2 + ...... + (in - infn) * SI * s2 * ... * sn- I
-,
IIIIII
I
:
elemento
v (il)
v (il' i2)v (il' i 2, i3)
dichiaratore divariabiledimensionata
v (di)
v (di' d2)v (di' d2, d3)
Dalla figura si deduce, in particolare, che gli elementi di un vettore sono dispo-sti in memoria nell'ordine crescente degli indici. . - - ------ - '
I",
162
Figura Il.3. Memorizzazione conseguente alla frase DIMENSION H(2 ,2,2).PROGRAM POLXCALCOLO DEL VALORE DI UN POLINOMIO DI GRADO N.LE.lOPARAMETER (NMAX = lO)DIMENSION A(O: NMAX)LETTURA DI NREAD *, NIF (N.LE.NMAX) THENLETTURA DEI COEFFICIENTI E DI X
DO IO 1= O,NREAD -. A(I)
CONTINUEREAD -. X
CALCOLO ESTAMPA DEL VALORE DEL POLINOMIOPOL = A(N)D020 I=N-I,O,-I
POL = POL * X + A(I)CONTINUEPRINT -. 'X =', X, 'POL(X) =', POL
ELSEIL VALORE DI N E' TROPPO GRANDEL'ESECUZIONE TERMINA CON LA STAMPA DI UN MESSAGGIO
PRINT *, 'N TROPPO GRANDE. NMAX =', NMAXENDIFSTOPEND
lO
20
n
p (x) = \"' a. xin L 1
i=O
per un assegnato valore ai x.
Il seguente programma si basa sull'identità
Pn(x) = «(anx + an_l) x + an_z)x + ... + al) x + ao'coefficienti del polinomio ao' ... , an sono memorizzati nel vettore A, mentre
il valore richiesto è memorizzato nella variabile PO L.
163
dei programmi. In assenza di controlli, una tale situazione non viene segnalata nel
momento in CUI si verifica e può condurre ad un risultato sbagliato o alla conclu
sione forzata dell'esecuzione del programma. Così, data la matrice MAT sopra
specificata, per effetto del riferimento a MAT (6,5) si andrebbe ad operare sulla
ventiseiesima locazione di memoria a partire da quella in cui è memorizzato
MAT (I, I), ossia su una locazione che non fa parte della memoria riservata a
MAT.
Nell'esempio seguente, come già si è fatto nell'esempio 10.10, si effettua un
controllo sui dati in ingresso per evitare il riferimento a elementi di un vettore
la cui posizione superi l'ampiezza del vettore stesso.
c
C
Esempio 11.14. Calcolo del valore di un polinomio di grado n ~ IO a coefficienti
reali
C
C
CC
65432
IA(l,I) A(2,1) A(l,2) A(2,2) A(l,3) A(2,3)
B(l,l ) B(2,1) B(3,1) B(l,2) B(2,2) B(3,2)
Elemento
Posizione
Elemento
B(l,I) B(I,2)
A(l ,1~A(l ,2/A(l ,3) BJ0J2lt ~ t ~ t
A(2,1) A(2,2) A(2,3) B(3,1) B(3,2)
D1MENSIONA(2, 3) D1MENSION B(3,2)
H(lì:~ H(l,2,2)
tH(2,1,2) H(2,2,2)
H(l,I,I) H(l,2,1)
~ -: ~H(2,1,I) H(2,2,IV
D1MENSION H(2,2,2)
Elemento
Posizione
Figura 11.2. Memorizzazione conseguente alla frase DIMENSION A(2,3), B(3,2).
INTEGER MAT (5, 5)
Figura Il.4. Memorizzazione delle variabili dimensionate A, B, H.
un riferimento all'elemento MAT (6, I) è sbagliato in F77, ma non in F66
in quanto la sua posizione è 6 < 25; il nome di elemento MAT (6,5) è invece
sbagliato anche in F66, in quanto ad esso corrisponderebbe la posizione 26 > 25.
Si noti che, nella pratica, un controllo diretto ad evitare che in fase di esecu
zione si verifichino situazioni non consentite del tipo ora esemplificato, comporta
u.n costo molto elevato in termini di tempo-macchina; per questo motivo la mag
gior parte dei compilatori lo attiva soltanto dietro esplicita richiesta del program
matore. Di solito è buona regola far attivare il controllo in fase di messa a punto
I'I\
.\\
I\ !
l
Li".I!;1
l
1M 165
Esempio 11.17. Il seguente programma H l O calcola e stampa gli elementi di una
matrice reale H quadrata di ordine lO; gli elementi hi,j con i, j = l, ... , n sono
definiti da:
Dagli esempi ora svolti è evidente che l'utilizzo del nome di una variabile di
n2ensioÌÙlta senza indici in una frase di lettura obbliga a fornire i dati nell'ordinein cui gli elementi sono disposti in memoria; analogamente, se lo si usa in una
frase di uscita, l'ordine in cui i contenuti degli elementi verranno stampati è quello
.p.r~stabi~~~~J!,el~boratore. In molte situazioni è utile poter stabilire un ordinediverso di ingresso o di uscita dei dati; nel cap. 13 si descriveranno tutte le possi
bilità previste in F77 per il trattamento delle variabili dimensionate nelle opera
zioni di ingresso/uscita.Consideriamo ora alcuni esempi di programmi che utilizzano variabili dimensionate.
11.5. Esempi di utilizzazione delle variabili dimensionate
Volendo scrivere dei programmi in cui si usano variabili dimensionate si pone il
problema di come poterle leggere e/o stampare. Nei paragrafi precedenti si è vistoche una lista di ingresso/uscita può contenere nomi di elementi di variabili di
! mensionate; d'altra parte in FORTRAN è consentito usare in una lista di ingres- I
1, J so/uscita il nome di una variabile dimensionata al posto della lista esplicita dei INl nomi di tutti i suoi elementi nell'ordine in cui figurano in memoria. j
Esempio 11.15. Dato il vettore
INTEGER V(7)
l'istruzione
PRINT ., V
significa che si devono stampare i contenuti Gei 7 elementi di V nell'ordine in
cui compaiono in memoria; in altri termini essa equivale a
PRINT., V(l), V(2), V(3), V(4), V(5), V(6), V(7)
h . -l,j
i + ji,j = l, ... , n.
Analogamente, si equivalgono le due trasi seguenti:
READ., VREAD -, V(l), V(2), V(3), V(4), V(5), V(6), V(7)
Esempio 11.16. Data la matrice
INTEGER A(2, 3)
l'istruzione
READ., A
indica che si devono leggere 6 dati interi e che il primo verrà memonzzato inA(l, l), il secondo in A(2, 1), e così via (cfr. fig. 11.2); la frase è quindi equiva-
lente a
READ., A(l,l), A(2,1), A(l,2), A(2,2), A(l,3), A(2,3)
L'istruzione
READ., A(l,1), A(l,2), A(l,3), A(2,1), A(2,2), A(2,3)
indica invece che si devono leggere tutti gli elementi di A, ma per righe anziché
per colonne. e non è quindi equivalente alle due precedenti.Supponendo ad esempio di voler leggere e memorizzare in A la matrice
2
5le prime due istruzioni di lettura impongono di fornire i dati nell'ordine
l 4 2 5 3 6,mentre la terza impone l'ordine seguente
l 2 3 4 5 6.
PROGRAM HlODlMENSION H(lO, lO)DO lO J = l, lODOlO 1=1,10H(I, J) = 1./(I + J)PRINT*, H(I, J)
lO CONTINUESTOPEND
Consideriamo ora il seguente programma HN:
PROGRAM HNPARAMETER(NM = lO)DIMENSION H(NM, NM)READ -. NDOlO J=I,NDO lO I = l, NH(I, J) = 1./ (I + J)PRINT *, H(I, J)
lO CONTINUESTOPEND
Se in ingresso è N = IO, il programma HN calcola gli stessi valori di HlU, men
tre se in ingresso è N < lO, tale programma assegna un valore soltanto ad
alcuni degli elementi della variabile H la cui ampiezza è uguale a 100.
Così, se è N = 5, viene definito il contenuto degli elementi corrispondenti alle
posizioni da l a 5, da 11 a 15, da 21 a 25, da 31 a 35, da 41 a 45, mentre non
viene assegnato alcun valore a tutti gli altri elementi.
~-------------_.
•167
10
Zj = L ai,j yj i = l, ... , lOj=l
Si osservi che le operazioni di ingresso/uscita in ORDVET riguardano un sot
toinsieme dei 20 elementi di X, e non si è quindi potuto usare la frase READ -. X
oppure PRINT *. X.
e DO lO 1 = 1,80010 1=1,8
Esempio Il.19. Data una matrice quadrata A di ordine lO ed un vettore y di IO
elementi, il seguente programma PRaD l O calcola e stampa il vettore prodotto
z = Ay; gli elementi di z sono definiti da
PROGRAM PRODIOREAL A(IO, IO), Y(IO), Z(IO)
C LETTURA DELLA MATRICE (PER COLONNE) E DEL VETTORE YREAD *, AREAD -. Y
C CALCOLO DEL VETTORE PRODOTTO ZDOlO 1=1,10Z(I) = O.DOlO J=I,10Z(I) = Z(I) + A(I, J) * Y(J)
lO CONTINUEC STAMPA DEI DATI E DEI RISULTATI
PRINT *, 'MATRICE DATA, PER COLONNE'PRINT *, APRINT *, 'vETTORE DATO v'PRINT -. YPRINT *, 'VETTORE PRODOTTO'PRINT *, ZSTOPEND
dove ai,j sono gli elementi di A e Yj quelli di y.
Osserviamo che in questo caso la dimensione del problema, ossia la dimensione
dei vettori e delle matrici interessate, è fissata a priori e non costituisce un dato.
Ciò consente di usare i nomi delle variabili dimensionate, senza indici, nelle frasidi ingresso/uscita.
E' interessante notare che PRaD l O può essere usato soltanto per problemi di
dimensione n = IO; se si vuole utilizzarlo, ad esempio, per n = 8, si deve sostituire la costante 8 alla costante lO nella frase REAL e sostituire le frasi
00101=1,10 e 0010 1=1.10
rispettivamente con le frasi
Esempio Il.18. L'algoritmo seguente permette di ordinare in senso crescente n
numeri reali dati Xl'···' Xn '
1. Leggi: n, xl' X2' , x n
2. Scrivi: xl' X2' , x n
3. Per i = I. ..., n - I
3.1. Poni min = i
3.2.Perj=i+ l, ... ,n3.2.1. Se xj < xmin : poni min = j e vai a 3.2.2;
altrimenti: vai a 3.2.2;
3.2.2. Continua il ciclo controllato da j
3.3. Se min > i: scambia xmin con xi e vai a 3.4
altrimenti: vai a 3.4
3.4. Continua il ciclo controllato da i
4. Scrivi: xl' X2' ... , x n
5. Stop
Supponendo n ~ 20, l'algoritmo viene realizzato dal seguente programma:
PROGRAM ORDVETD1MENSION X(20)
C LETTURA DEI DATI. SI SUPPONE N.LE.20READ *, NDOlO 1=I,NREAD *, X(I)
IO CONTINUEPRINT -. 'VETTORE DATO'DOl5 I=I,NPRINT *, X(I)
15 CONTINUEC RIORDINAMENTO DEGLI ELEMENTI DI X
DO 50 I = l, N - IMIN=IDO 45 J = I + I, NIF (X(J).LT.X(MIN)) MIN = J
4S CONTINUEIF (MIN.GT.I) THEN
TEMP = X(MIN)X(MIN) = X(I)X(I) = TEMP
ELSEENDIF
50 CONTINUEC STAMPA DEL VETTORE RIORDINATO
PRINT -. 'vETTORE RIORDINATUD055 I=I,NPRINT *, X(I)
55 CONTINUESTOPEND
166
168
Esempio Il.20. Si vogliono calcolare le seguenti medie relative ai voti riportati
in 8 materie dai 60 alunni afferenti a tre classi di 20 alunni ciascuna:
1) la media dei voti riportati da ciascun alunno in ognuna delle tre classi;
2) la media dei voti per ciascuna materia in ognuna delle tre classi.
Tutti i dati possono essere contenuti in una variabile a tre dimensioni, di nome
V, in cui l'elemento vi,i,k indica il voto riportato nella j-esima materia dall'i-esimo
alunno della k-esirna classe; così gli indici di riga possono variare da l a 20,
quelli di colonna da 1 a 8, quelli di piano da l a 3.
I risultati dei calcoli sono contenuti in due matrici, MEDAL e MEDMAT: la
prima, di 20 righe e 3 colonne, contiene le medie relative al punto 1); la seconda,
di 8 righe e 3 colonne, contiene quelle relative al punto 2).
PROGRAM MEDIEC CALCOLO DELLE MEDIE PER ALUNNI E PER MATERIE
PARAMETER (NALUN = 20, NMAT = 8, NCLAS = 3)INTEGER V (NALUN, NMAT, NCLAS)REAL MEDAL (NALUN, NCLAS)REAL MEDMAT (NMAT,NCLAS)
C LETTURA DEI DATI,PER CLASSE,PER MATERIA, PER ALUNNOREAD -. V
C CALCOLO DELLE MEDIE RICHIESTE PER OGNI CLASSEDO 35, K = l, NCLAS 3
C CALCOLO DELLE MEDIEDEGLI ALUNNI DELLA K-ESIMA CLASSEDO lO, I = l, NALUNMEDAL (I, K) = O.DO S, J=I,NMATMEDAL (I, K) = MEDAL (I, K) + V(I, J, K)CONTINUEMEDAL (I, K) = MEDAL (I, K)/ NMAT
lO CONTINUEC CALCOLO DELLE MEDIERELATIVE AD OGNI MATERIAC NELLAK-ESIMA CLASSE
DO 20, J = l, NMATMEDMAT (J, K) = O.DO 15, I=I,NALUNMEDMAT (J, K) = MEDMAT (J, K) + V(I, J, K)
15 CONTINUEMEDMAT (J, K) = MEDMAT (J, K)/ NALUN
~O CONTINUE30 CONTINUE
C STAMPA DELLE MEDIE PER CLASSE,PER ALUNNOPRINT *, MEDAL
C STAMPA DELLE MEDIE PER CLASSE,PER MATERIAPRINT *. MEDMATSTOPEND
Si osservi che la frase READ *, V prevede la lettura dei 480 dati nel seguente
ordine: per ogni classe si devono fornire i voti riportati da tutti gli studenti nella
169
prima materia, poi i voti riportati da tutti nella seconda materia, e così via. Se i
dati non fossero disponibili in questo ordine si sarebbe costretti a riordinarli nel
modo imposto dal programma.
Esempio Il.21. Dati due vettori x, y di elementi xl' ... ,xn e Yl' ... 'Y n rispet
tivamente, si vuole calcolare il prodotto scalare p, definito da
In [14] è dimostrato che l'accumulo degli errori di arrotondamento nel cal
colo del prodotto scalare in precisione finita può essere notevole per alcune
scelte di x e Y e che può essere ridotto se si ha modo di eseguire le operazioni
con una precisione maggiore di quella in cui sono memorizzati i dati. Nel pro
gramma seguente si calcola il prodotto scalare P in doppia precisione, mentre i
dati X e Y sono in precisione semplice. Si utilizza inoltre una variabile ausiliaria
D per poter eseguire tutte le operazioni in doppia precisione.
PARAMETER (N = lO)REAL X(N), Y(N)DOUBLE PRECISION D, PREAD*,X,YP = O.DODO 25 I = I, ND = X(I)p =P + D * Y(I)
25 CONTINUEPRINT -. 'VETTORE X v:', XPRINT *, 'VETTORE Y v .; YPRINT *, 'PRODOTTOSCALAREv:', PSTOPEND
Esempio Il.22. Data una matrice quadrata A, di ordine n, si vogliono calcolare
prodotti scalari p(j, k) fra la colonna j-esima e la colonna k-esima, definiti dan
p( j, k) = '\' a . a kL l,) l,
i= 1
per j = l, ... , n - l e k = j + 1, ... ,n. Si vuole inoltre interrompere il
calcolo appena si trova una coppia di valori (j ,k) per cui è Ip(j, k) I> E, dove
E> O è una costante assegnata. In questo caso l'esecuzione termina con la stampa
dei valori di j, k e p(j, k ). Se invece tutti i valori calcolati p(j, k ) sono in valore
assoluto minori o uguali di E. l'esecuzione termina con la stampa di un messaggio
che segnala tale situazione.
T171
scrivi: tutti i prodotti p sono "piccoli»
l ' ',', IDlMENSION VETT (O : 8)
DlMENSION APICE (8 : O)
REAL REC, REM (20,20)DlMENSION REC, REM (20, 20)
INTEGER MAT (5., 3,2) r (
DlMENSION ALFA (- 5, 2) /0 C
DlMENSION ALFA (- 5 : 2)
Il.5 Con riferimento alle variabili dimensionate dell'esercizio precedente, indi
care quali fra i seguenti nomi di elementi sono sbagliati:BETA (2,3,4) GAMMA (2) DELTA (2) ALFA (2,3,4) ALFA (1,1)
EPSIL(3,4) ZETA (23,1) DELTA (O) ETA (2,3,4) ETA (2,33)
11.2 Scrivere opportune dichiarazioni per le variabili dimensionate qui di seguito
descritte:a) la matrice intera DAMA, di 12 righe e 12 colonne, con indici maggiori o
uguali di l;b) la matrice intera DAMB, di 12 righe e 12 colonne, con indici maggiori o
uguali di - 6;c) la matrice complessa COMP, con indici di riga variabili fra - 5 e 5 e indici
di colonna fra - 3 e 3;d) la variabile TRIANG, di tipo doppia precisione, di 3 righe, 5 colonne
e 4 piani, e indici non negativi;e) il vettore intero STATUS, con indici variabili fra - n e n, con n = 20.
11.3 Scrivere i dichiaratori di opportune variabili dimensionate atte alla memo
rizzazione dei seguenti insiemi di dati:a) le temperature minima e massima rilevate in 20 stazioni metereologiche il
19 ottobre 1986;b) le temperature minima e massima rilevate in 20 stazioni metereologiche
nei giorni dal 20 al 26 ottobre 1986;c) i valori che la funzione f(x) = cosx assume nei punti xj = j ;- , per j = l,
.. , ,n;d) i valori che la funzione f(x, y) = x 2 + cos (xy) assume nei punti
(xi' Yk) = (j ; , k ;) con j, k = O, I, ... , n.
11.4 Indicare l'ampiezza delle seguenti variabili dimensionate:REAL ALFA (2:3,4), BETA (2,3,4), GAMMA (2,3:4), DELTA (234)
DOUBLE PRECISION EPSIL(2:3,4), ZETA(23,4), ETA (2,34).
EserciziIl.1 Individuare quali fra le seguenti frasi dichiarative sono sbagliate e spiegarne
il motivo:
per j = \, ... , n - I
Figura 11.5. Diagramma di flusso relativo all'esempio 11.22.
Il programma PROD che segue risolve il problema per n.ç l O, realizzando il
diagramma di fig. 11.5. Si osservi che in PROD si utilizzano due variahili ausi
liarie, D e DP, in doppia precisione per poter effettuare i calcoli con una pre
cisione maggiore di quella in cui sono memorizzati i dati e i risultati. Si osservi
inoltre che nel programma non si memorizzano tutti i valori p(j, k), bensi si usa
una variahile non dimensionata P per memorizzarli temporaneamente via via che
vengono calcolati.
PROGRAM PRODREAL A(IO, IO). P, EPSDOUBLE PRECISION D, DPREAD -. N. EPSDOl5 1=I,ND015 J=I,NREAD -, A (I, J)
15 CONTINUEDO I 50 J = I, N - I
D0140 K=J+I,NDP = O.DO00120 1=I,ND = A(I,J)DP = DP + D * A(I, K)
120 CONTINUEP= DPIF (ABS(P).LE.EPS) GOTO 140PRINT -. J, K, PSTOP
140 CONTINUE150 CONTINUE
PRINT -, 'P(1, K).LE.', EPS, 'PER OGNI (1, K)'STOPEND
170
j!
~ i
!l
'I, "
12Elaborazione delle informazionidi tipo carattere
DELTA (1)
ZETA (3 ** I, I)
DELTA (J + 1** 2)GAMMA (I, (I + 1)/3)
fra i seguenti nomi sono sbagliati e
BETA (2,3, 1/1) GAMMA (2, 1 - 7)
ZET A (I, 3 ** I)
ALFA (ABS(I- 5), 1/3)ETA (I, 1 -I)
Se 1= 2, 1 = IO, X = 3.14159, qualiperché?ALFA (1,1)
EPSIL (I, l/X)ETA (lNT(X), 34)ETA (J - I, I)
172
Il.6 Sono dati il vettore intero M e la matrice reale A dichiarati da
DIMENSION M (10), A( 10, lO)
Supponendo che il contenuto di M sia definito dalla sequenza di istruzioni
DOI3I=I,1O
M(I) = 2 * I - I13 CONTINUE
indicare la posizione corrispondente ai seguenti elementi:M(5), M(M(l)), M(M(2)), M(l + M(5»), M(lO), IA(l, lO), A(lO, l), A(M(5), M(4»), A(M(7)/3, lO), A(M(2) ** 2, I).
Nei capitoli precedenti si è più volte accennato al fatto che un calcolatore puòelaborare insieme alle informazioni di tipo logico o numerico anche informazionidi tipo carattere ovvero informazioni quali le lettere dell'alfabeto, le parole diun testo, i segni di interpunzione, etc. Negli ultimi anni, la manipolazione ed
elaborazione di informazioni di tipo carattere (word processing) ha notevol
mente allargato le possibilità di applicazione degli elaboratori assumendo una
importanza sempre crescente che si manifesta anche nelle nuove possibilità di
gestione dei caratteri offerte dall'ultima versione standard del FORTRAN.
11.7 Scrivere un programma che permetta di definire gli elementi di una matrice
reale A di 5 righe e 7 colonne e di calcolare e stampare il massimo fra i valori
assoluti degli elementi di ciascuna riga. Provare la correttezza del programmaavendo come dato la matrice A i cui elementi a. . sono definiti da
l,l
i;;;:. ji + j
ai,j =i + j
i <i2i + 3j
11.8 Scrivere un programma che permetta di memorizzare in un vettore V le som
me degli elementi di ciascuna colonna di una matrice reale B di ordine
n~ 15. Il programma deve inoltre riordinare in senso decrescente gli ele
menti di V e stampare il vettore così ottenuto.
11.9 Scrivere un programma che permetta di leggere per colonne gli elementi di
una matrice A quadrata di ordine n ~ lO e calcolare e stampare le norme
Il A II~ e Il A 111' dove
12.1. Memorizzazione dei caratteri
Le informazioni di tipo carattere vengono memorizzate in unità di memoria
dette unità di memoria carattere ciascuna delle quali è in grado di contenere la
codifica binaria di un solo carattere. Le modalità con cui vengono codificati i
caratteri dipendono dal sistema usato che stabilisce anche la lunghezza di ogni
singola unità di memoria carattere. Y!!~~!na di codifica molto diffuso è quello
A~CIL~he, utilizzando 7 bits per la codifica di un carattere, permette di codificare 127 caratteri distinti. Un altro codice è quello EBCDIC che utilizza 8 bitsper la memorizzazione di un singolo carattere. Con il co~Ùce-EBCDIC è possibile
definire ed utilizzare 256 caratteri diversi. Sia il codice ASCII che quello EBCDICsono riportati in appendice A4.
Le unità di memoria carattere sono quindi completamente diverse e nettamente distinte da quelle numeriche che, ricordiamo, sono destinate a contenereinformazioni di tipo numerico o logico. Tale distinzione è chiaramente sottolineata dallo standard F77 che definisce dato di tipo carattere una qualunque succes
sione (stringa) di caratteri codificabili su un elaboratore ed associa ad ogni dato ditipo carattere la sua lunghezza definita come il numero di caratteri che lo costi
tuiscono. Un dato di tipo carattere è quindi memorizzato in tante unità di memoria carattere contigue quante sono quelle specificate dalla sua lunghezza.
•I
174175
Esempio 12.2. La frase:
CHARACTER * 12 XI, X2, X3 * IO.
CHARACTER * 7 A, B, H * 3, C, D
CHARACfER * I A, B, C
CHARACTER A * I, B * 5, C * ICHARACTER XY * 4
CHARACTER X * 33. Y * 33
che equivale a
che equivale a
che equivale a
che equivale a
CHARACTER A, B, C
CHARACTER A, B * S, C
CHARACTER * 4 XY
CHARACTER * 33 X. Y
lunghezza di nomi simbolici di costanti (ulteriori utilizzazioni di questo specificatore sono indicate nel cap. 15).
Lo specificatore di lunghezza ~ che segue la parola chiave CHARACTER fissa
la lunghezza per tutte le entità carattere individuate dai nomi simbolici nl' ... , nrmentre ogni specificatore di lunghezza che segue un nome sim bolico si riferisce
soltanto alla entità individuata da quel nome. Gli specificatori che fissano lun
ghezze uguali ad uno possono essere omessi insieme all'asterisco che li precede.
In una frase CHARACTER è sempre possibile specificare la lunghezza di una
entità di tipo carattere facendo seguire il corrispondente nome simbolico da
un asterisco e da uno specificatore di lunghezza. In_particolare è possibile indicare
una lunghezza diversa da quella fissata dallo specificatore Q che segue la parola
chiave; in questo caso lo specificatore di lunghezza Q fissa la lunghezza per tutte
le entità i cui nomi sim bolici non sono seguiti da un loro specificatore di lunghezza che, in generale, è diverso da Q.
CHARACfER A * 7, B * 2, C * (3 + 8)
specifica che A, B e C sono entità carattere la cui lunghezza è rispettivamenteuguale a 7, 2, II.
Altri esempi di dichiarazione esplicita di tipo carattere sono i seguenti:
Esempio 12.1. La frase dichiarativa di tipo:
CHARACTER * 7 A, B, C
specifica che A, B e C sono entità carattere ciascuna delle quali contiene esattamente 7 caratteri. La frase.
specifica che A, B, C, D sono nomi simbolici di entità carattere la cui lunghezza
è uguale a 7 mentre H indica il nome di una stringa di caratteri la cui lunghezza
è uguale a 3; analogamente, per dichiarare che le varia bili X I, X2 e X3 sono di ti.
po carattere ed hanno lunghezza rispettivamente uguale a 12, 12, IO si può usarela frase:
dove:
• CHARACfER è la parola chiave che identifica la frase;
• n l , n2, ... , n r sono nomi simbolici; . .. .• Q Q ,Q2" .. , Q sono specificatori di lunghezza ciascuno del quali può essere., I r
- una costante intera positiva non preceduta dal segno +;- una espressione costante intera che deve avere valore positivo e deve essere rac-
chiusa tra parentesi; ..- un asterisco racchiuso tra parentesi (*) che può essere usato per specificare la
Variabili carattere
Le variabili di tipo carattere (variabili carattere) vengono indicate mediante un
nome simbolico; il loro tipo deve essere specificato mediante una opportuna frase
dichiarativa nella quale sono indicati sia il nome della variabile che la sua lun
ghezza.
Dichiarazione esplicita del tipo carattere
Per specificare il tipo e la lunghezza di una entità di tipo carattere è possibile
usare una delle seguenti forme della frase dichiarativa CHARACfER:
CHARACTER .. Q "l' "2' ..., nr
CHARACTER "r " QI' "2 .. Q2' ... , "r .. Qr
12.2. Le costanti e le variabili di tipo carattere
Costanti carattere
Una costante di tipo carattere (costante carattere) è scritta in FORTRAN
come una successione di caratteri racchiusa tra apici. Gli apici che racchiudono la
costante non fanno parte di essa e quindi tra i due apici che delimitano una co
stante carattere deve esserci almeno un carattere che può essere anche il carat
tere di spaziatura (blank). Una costante carattere può essere costituita sia da ca
ratteri facenti parte dell'alfabeto FORTRAN che da caratteri diversi qual:, ad. <:;;;. [ l?' . % purché codificati sul sistema di calcolo usato. L apo-esempiO, ,"'-, ".,.,,,
strofo è rappresentato da una coppia di apici consecutivi. . .
Indicato con v il carattere di spaziatura sono esempi di costanti carattere I se
guenti:
'BUONGIORNO' '1987' 'COMEvSTAI?' 'c"ERA' 'vUNv' 'v'.
Si osservi che la costante '1987' rappresenta la successione di quattro caratteri:
I, 9, 8, 7 e non il numero 1987. . .
La l',lghezza di una costante carattere è il numero dei caratte~ ~resentl tra gliapici, compresi eventuali caratteri di spaziatura; il doppio apice u~iliz_z~~._~er~ap
'--\-- presentare l'apostrofo conta come un_unico carattere. Così le sei costanti pnma
~~riit~hannorispettivamente lunghezza 10,4, IO, 5, 4, l.
Il
,l
176
Esempio 12.3. Consideriamo la seguente successione di frasi dichiarative:
PARAMETER (LUN = 6, L = 8)CHARACTER • (LUN) VOCE, TIPO, ART. (L)PARAMETER (ART = 'ARTICOLO').
La prima frase PARAMETER stabilisce il valore degli specificatori di lunghezza
usati nella dichiarativa CHARACfER; la seconda frase PARAMETER assegna in
vece alla costante carattere'ARTICOLO' il nome simbolico ART. Questa succes
sione di istruzioni serve allora a specificare che VOCE e TIPO sono due variabili
carattere di lunghezza uguale a 6 mentre ART è il nome simbolico della costantecarattere'ARTICOLO' di lunghezza 8.
Come si vede anche da questo esempio quando la frase CHARACfER è usata
per dichiarare il tipo di un nome simbolico di costante, il valore di questa costante
deve essere specificato in una frase PARAMETER che segue la dichiarativa
CHARACfER. In questo caso la lunghezza della costante carattere può essere in-
. dicata mediante lo specificatore (.) che chiameremo specificatore di lunghezza in
defi.'!!ta; la sua utilizzazione ha l'effetto di specificare, pedeeritiiàCa~attere'indi
viduate da nomi simbolici di costante, una lunghezza uguale a quella delle corrispondenti costanti che compaiono nella frase PARAMETER. In ogni caso, una
volta fissata, la lunghezza di un nome simbolico di costante carattere non deveessere più modificata.
Esempio 12.4. Le frasi:
CHARACTER • ( • ) SP, CARPARAMETER (SP = 'SPECIFICAZIONE', CAR = 'CARATTERE')
servono a specificare che SP e CAR sono nomi simbolici di due costanti carattere la
cui lunghezza è uguale, rispettivamente, a quella delle costanti 'SPECIFICAZIONE'
e 'CARATIERE' indicate nella dichiarativa PARAMETER. Pertanto SP halunghezza 14 e CAR ha lunghezza 9.
Esempio 12.5. La successione di istruzioni:
PARAMETER (LUN = 6)CHARACTER • (LUN) VOCE, TIPO, ART. (.)PARAMETER (ART = 'ARTICOLO')
ha lo stesso effetto di quella indicata nell'esempio 12.3. In questo caso la lunghez
za della costante il cui nome simboli co è ART è determinata da quella della co
stante 'ARTICOLO' ed è quindi uguale a 8. Se la seconda frase PARAMETERvenisse sostituita da
l
177
PARAMETER (ART = 'ARTICOLO V'DAV' REGALO')
il nome simbolico ART indicherebbe una costante carattere di lunghezza uguale
a 18.
Dichiarazione implicita del tipo carattere
Analogamente a quanto detto per le entità di tipo numerico o logico è possi
bile indicare in un programma FORTRAN che una o più lettere dell'alfabeto,
se usate come iniziale di un nome simbolico, ne determinano il tipo carattere.
La frase che permette la dichiarazione implicita del tipo carattere ha la forma:
IMPLICIT CHARACfER * {I (al' a2, ••• , am)
dove:• IMPLICIT CHARACfER è la parola chiave che identifica la frase;
• Q è uno specificatore di lunghezza diverso da (*);
• al' a2, ... , a
msono singole lettere oppure gruppi di lettere ordinate alfabetica
mente di cui viene indicata la prima e l'ultima lettera separate da un segno meno.
Nella dichiarazione im!'.li~~~u~~.tip().!\on è quindi l::0!1~~!!!i!~l'_~~odello specificatore di lunghezza indefinita;)noltre, i nomi il cui tipo è implicitamente speci
ficato dalla frase IMPLICIT CHARACfER indicano stringhe di caratteri che
hanno tutte la stessa lunghezza: quella fissata dallo specificatore Q. Così, ad esem
pio, la frase:
IMPLICIT CHARACfER * 16 (A - C)
specifica che i nomi simbolici che iniziano con le lettere A, B, C indicano entità
di tipo carattere di lunghezza 16. Una dichiarazione esplicita di tipo può modifi
care il tipo o la lunghezza delle entità i cui nomi hanno una lettera iniziale pre
vista in una istruzione IMPLICIT CHARACTER.
Esempio 12.6. La successione di istruzioni:
IMPLICIT CHARACTER. 16 (A - C)REA L ANNA, CARLOCHARACTER • 8 BABBO
ha l'effetto seguente: tutte le variabili i cui nomi hanno come lettera iniziale
A, B oppure C sono considerati di tipo carattere e la loro lunghezza è uguale a 16
unità di memoria carattere. Fanno eccezione ANNA e CARLO che indicano
variabili reali e BABBO che indica una variabile carattere di lunghezza 8. Si noti
che la dichiarazione implicita di tipo precede quella esplicita secondo le regole
già viste nel § 5.3.
178 179
Esempio 12. 7. caratteri. Una sottostringa è identificata da un nome la cui forma è la seguente:
Esempio 12.11. Sia AI una variabile carattere di lunghezza 5 il cui contenuto è
la stringa GAMMA. Indichiamo, accanto ad ogni nome. i caratteri che costitui
scono alcune sottostringe estratte da A I e le relative lunghezze.
Esempio 12.10. Supponendo che ALFA sia una variabile carattere di lunghezza 8e BETA sia un vettore carattere di tre componenti di lunghezza 5, il nome simbo
lico ALFA(2 : 5) indica la sottostringa formata dal secondo, terzo, quarto e quin
to carattere della stringa di nome ALFA mentre BETA(2)( 1: 3) identifica la
sottostringa costituita dai primi tre caratteri di BETA (2).
dove:
• v è il nome della variabile carattere o dell'elemento di variabile carattere
dimensionata da cui si estrae la sottostringa;
• et, e2 sono due espressioni intere dette espressioni di sottostringa. II valore di
et specuica la posizione nella variabile v del carattere più a snustra della sotto
stringa mentre il valore di e2
specifica quelIa del carattere più a destra. I valori di
et ed e2 devono essere tali che 1 ~ et ~ e2 ~ Q dove Q è la lunghezza di v.
3
I
Lunghezza
5
Contenuto
GAMMA
AM
MA
GAM
A
Sottostringa
Al (:)
A I (2 : 3)
Al (4 :)
A l( : 3)
Al(2:2)
In un nome sim bolico di sottostringa possono essere omesse una o entrambe
le espressioni di sottostringa: l'omissione di et equivale ad e, = l, quella di e2 equi
vale ad e2 = Q; se entram be le espressioni sono omesse il nome della sottostringa
ha la forma v(:) e la sottostringa coincide con l'intera stringa v.
La lunghezza di una sottostringa è data da e2 - e, + l. Pertanto, se il valore di
e, è uguale a quello di e2 la sottostringa è costituita da un unico carattere, quello
che nella stringa v occupa la posizione indicata da et e da e2
.
Variabili carattere dimensionate
Nel capitolo precedente è stata sottolineata l'opportunità di utilizzare variabili
dimensionate che, ricordiamo, possono essere anche di tipo carattere. La frase
dichiarativa CHARACTER può essere utilizzata per specificare i nomi delle even
tuali variabili dimensionate, il numero e la lunghezza dei loro elementi. ~?-g~i
caso, tutti gli elementi di una variabile carattere dimensionata devono avere)~
stessa lunghezza ed è pertanto proibito usare variabili carattere dimensionate che
siano costituite da elementi di lunghezza diversa l'uno dalI' altro.
CHARACTER * lO VOCE (5)
Esempio 12.8. La frase:
Esempio 12.9. La successione di istruzioni:
IMPLICIT CHARACTER. 25 (A)DIMENSION ART (IO)
serve a specificare che le variabili i cui nomi sim bolici iniziano con la lettera A
sono di tipo carattere ed hanno lunghezza 25; inoltre ART è un vettore carattere
di lO elementi ciascuno dei quali è costituito da 25 caratteri.
specifica che VOCE è una variabile dimensionata costituita da cinque elementi
di tipo carattere ciascuno dei quali ha lunghezza uguale alO.
PARAMETER (LUN =3)IMPLICIT CHARACTER. (LUN + 2) (A - C F, M)CHARACTER F I • (LUN + I), MAM • 15PARAMETER (FI = 'CANE', F2 = 'GATTO')
La prima frase PARAMETER fissa il nome LUN per la costante 3; la seconda
frase stabilisce che tutti i nomi che iniziano con le lettere A, B, C. F, M si riferi
scono a quantità carattere di lunghezza uguale a 5; la terza frase specifica che F 1
e MAM, pur essendo sempre di tipo carattere, hanno però una lunghezza diversa
rispetto a quelIa specificata implicitamente: F 1 ha lunghezza 4 e MAM ha lun
ghezza 15; la quarta frase infine assegna alla costante 'CANE' il nome simbolico
Fl ed alIa costante 'GATTO' il nome simbolico F2. Si osservi che 'CANE' e
'GATTO' sono costituite rispettivamente da 4 e da 5 caratteri.
li
I
II
II\i\
I
!i IIl
!\
liI
12.3. Sottostringhe ed espressioni carattere
Sottostringhe
Con il termine sottostringa si indica in F77 una entità di tipo carattere costi
tuita da un qualunque sottoinsieme di caratteri contigui estratti da una stringa di
Espressioni carattere
Una espressione carattere è costituita, nella sua forma più semplice, da una
delIe seguenti entità carattere: costante, variabile, elemento di variabile dimen
sionata, sottostringa. Espressioni carattere più complesse possono essere formare
usando l'operatore concatenazione che viene indicato con il simbolo Il e che
180181
opera tra due operandi di tipo carattere. Se xl ed x2
indicano due entità carat
tere il risultato dell'operazione
è una stringa carattere il cui valore è quello di xl seguito dal valore di x2.
Esempio 12.12. Il valore dell' espressione carattere:
'LIN' Il 'GUAGGIO'
è la stringa LINGUAGGIO ottenuta congiungendo in un'unica stringa i valori
delle costanti 'LIN' e 'GUAGGIO'. Analogamente l'espressione:
'LINGUAGGIO' Il 'v' Il 'FORTRAN' Il '77'
Esempio 12.14. La successione' di istruzioni:
CHARACTER * 4 VETT(5), A(2, 2)VETT(l) = 'CANE'VETT(2) = 'LUPO'VETT(3) = 'GUFO'VETT(4) = 'IENA'VETT(5) = 'TOPO'DO IO I = 1,2DO IO J = 1,2A(I, J) = VETT (2 * J - 2 + I)
lO CONTINUE
specifica la lunghezza ed il contenuto sia delle cinque componenti del vettore
carattere VETT che dei quattro elementi della matrice carattere A.
ha il seguente valore:
LINGUAGGIOvFORTRAN 77.
Esempio 12.15. Sia A I una variabile carattere il cui valore è la stringa NUOVO.
L'esecuzione della frase:
A\(4 : 4) = 'T'
Esempio 12.16. Consideriamo la successione di istruzioni:
Dopo l'esecuzione di queste istruzioni V(I), V(l) e V(3) contengono rispettiva
mente i valori:
sostituisce. il quarte carattere di A I con la lettera T. II contenuto di A l diventa
quindi la stringa NUOTO.
CHARACTER * 6 V(3), Al * LU, AL * I~
Al = 'ILvGATTOvEvLAvVOLPEv'A2 = 'ILvGRILLOvPARLANTE'V(l) = Al(4 : 9)V(2) = AI(l5 :)V(3) = A2(4 : 9)
GRILLOVOLPE vGATTO v
v = espressione carattere
12.4. Assegnazione fra stringhe di caratteri
Come è stato sottolineato nel cap. 7, la frase di assegnazione può essere definita
anche tra variabili ed espressioni di tipo carattere. La forma generale della frase
è in questo caso:
dove:
• v è il nome di una variabile carattere, di un elemento di variabile carattere di
mensionata, di una sottostringa.
L'esecuzione di questa frase implica la valutazione dell'espressione carattere
e la successiva definizione di v il cui valore viene posto uguale a quello dell'espres
sione se la lunghezza di v è uguale a quella del valore dell'espressione carattere.
Esempio 12.13. La successione di istruzioni:
CHARACTER * 7 AN, SAN = 'CAVALLO'
S=AN
permette di memorizzare l'informazione carattere 'CA VALLO' nelle variabiliAN ed S.
In una frase di assegn...a. zione la variabile v può avere lunghezza diversa dal
<.~./valor~Q.cll'espressionecarattere;in questo caso la stringa che costituisce il valore "
. dell'espressione viene opportunamente «allungata» o «troncata» prima di effet
tuare l'assegnazione. A questo proposito il FORTRAN specifica che se la lunghez
~--di. v~ ~~g~iore di quella del valore dell'espressione, quest'ultimo viene allun
gato con l'aggiunta, alla sua destra, di tanti caratteri blank quanti ne servono
per uguagliare la lunghezza di v; se la lunghezza di v è invece inferiore a quella
del valore dell'espressione carattere, quest'ultimo viene accorciato togliendo, alla
________________-----J..-------- _
182
sua destra, tanti caratteri quanti ne occorrono per uguagliare la lunghezza di v.
r183
razioni di concatenazione e le frasi di assegnazione tra stringhe di lunghezza
diversa.Esempio 12.17. Sia A una variabile carattere di lunghezza 6. Indichiamo, accanto
ad alcune frasi di assegnazione, il contenuto di A:
Esempio 12.18. Sia DATO una variabile carattere di lunghezza uguale a 5. Esami
niamo l'effetto dell'esecuzione sequenziale di alcune frasi di assegnazione.
Frase di assegnazione
A= 'UN'
A = 'VELOCEMENTE'A = 'PINO'II'LORO'
Frase di assegnazione
DATO = 'FERRO'DATO (I :4) = 'CORT'DATO (4:4) = 'V'DATO (2:2) = 'ERBA'DATO (4 :) = 'A'
Contenuto di A
UNVvvvVELOCEPINOLO
Contenuto di DATU
FERROCORTOCORVOCERVOCERAV
Esempio 12.19.
CHARACTER VAR * 8, TAR * IOVAR = 'AUTO'
TAR = VAR l l 'MOBILE'
La prima frase di assegnazione colloca la stringa AUTO nelle prime quattro
posizioni di VAR il cui contenuto è completato da caratteri di spaziatura fino a
raggiungere la lunghezza di 8 caratteri fissata per VAR. Per eseguire la seconda
frase di assegnazione si valuta l'espressione carattere VAR /1 'MOBILE' il cui
valore, AUTOvvvvMOBILE, è costituito da 14 caratteri ed è quindi troncato
in AUTOvvvvMO prima di essere assegnato come contenuto della variahile
TAR. Un risultato diverso sarebbe stato ottenuto concatenando una sottostringa
di VAR con la costante carattere 'MOBILE' ovvero usando la frase di assegnazione
TAR = VAR (: 4) Il 'MOBILE'.
Le ultime due frasi dell'esempio precedente mettono in evidenza che, al mo
mento della assegnazione, si applica sempre la regola di «aggiustare opportuna
mente» la lunghezza del valore dell'espressione in modo che essa coincida conquella di v anche quando v è una sottostringa.
Si osservi che in una frase di assegnazione tra stringhe di caratteri è proibitaqualunque sovrapposizione tra le unità di memoria carattere che costituiscono
v e quelle utilizzate dall'espressione. Pertanto sono sbagliate le frasi seguenti:
DATO (I :4)='LE' Il DATO (2 :8)DATO = DATO (l : 3) Il VARDATO = DATO (: 2) Il DATO (9:)DATO (3: 5) = DATO (4: 4) Il DATO (l : 3)
in quanto in ognuna di esse la valutazione dell'espressione carattere coinvolge
l'elaborazione di sottostringhe che si sovrappongono con quelle indicate a sinistra
del simholo di assegnazione. Sono invece esempi di frasi corrette i seguenti:
DATO (I :4) = 'LE' Il DATO (5 :8)DATO (4:) = DATO (: 3)
DATO (3 :5)=DATO(:2)IIDATO(6 :6)DATO (2 : 2) = DATO (3: 3)
L'esempio seguente serve ad evidenziare quali effetti possano produrre le ope-
L'espressione carattere che compare in questa frase ha infatti come valore la
stringa AUTOMOBILE.
12.5. Lettura e scrittura dei dati di tipo carattere
Le frasi di ingresso/uscita guidate dalla lista introdotte nel cap. 8 possono essere
usate per leggere e scrivere quantità di tipo carattere; altre possibilità per effet
tuare queste operazioni verranno presentate nel prossimo capitolo. Si ricordi che
le costanti carattere possono far parte di una lista di una frase PRINT* ma non
di una READ* mentre sia la lista di ingresso che quella di uscita possono conte
nere nomi simbolici di entità carattere.
Esempio 12.20.
CHARACTER * 8 AN I, AN2READ *, N, M, ANIAN2 = 'V PECORE v'PRINT -. 'ClvSONOv', N, AN2, 'vEV', M, ANISTOPEND
Il significato e l'effetto di queste istruzioni è di immediata comprensione e
non necessita di ulteriori spiegazioni, Si deve però osservare che i dati devono
. \
184
essere fomiti in modo opportuno: i primi due dati devono essere costanti intere
e saranno quindi costituiti da una stringa di cifre decimali mentre il dato di
tipo carattere sarà costituito da una costante di lunghezza 8 (per esempio
'v MUCCHEv').
Per quanto riguarda l'operazione di lettura guidata dalla lista si deve tenere
presente che essa equivale ad una frase di assegnazione nel senso che permette
di definire il contenuto di una variabile o di una sottostringa di caratterL!'.~r
tanto, se la lunghezza del dato fornito in ingresso non è uguale a quella stabilita
per la corrispondente variabile o sottostringa, essa viene automaticamenteaggiu
stata togliendo caratteri a destra del dato o aggiungendo caratteri di splgia!,:!ra
sempre a destra del dato secondo le modalità viste per le frasi di assegnaz~e.
Esempio 12.21. Sia VAR una variabile carattere di lunghezza 5 il cui valore viene
definito dalla frase di ingresso
REA D *, VAR
Se viene fornito il dato' AUTOMOBILE', il valore di VAR è costituito dai primi
cinque caratteri di questa stringa ovvero VAR vale AUTOM; se in ingresso viene
fornita la stringa 'AUTO' il valore di VAR è AUTOv.
Nelle operazioni di scrittura guidate dalla lista il numero di caratteri che devono
essere riprodotti in uscita è determinato dalla lunghezza della espressione carat
tere che compare nella lista di uscita: il valore dell'espressione viene interamente
riprodotto sul mezzo di uscita standard.
Esempio 12.22.
CHARACTER TESTO * 3TESTO = 'F77'DO lO 1= 1,3PRINT ... , TESTO (I : I)
lO CONTINUESTOPEND
L'esecuzione di questo programma produce la scrittura dei singoli caratteri
della stringa F77 su righe successive, ovvero:
F7
7
185
12.6. Confronto tra espressioni carattere
E' possibile utilizzare gli operatori di relazione .GT., .LT., .GE., .LE., .EQ.,
.NE. definiti nel §6.2 per eseguire confronti tra due stringhe di caratteri ovvero è
possibile definire ed utilizzare una espressione relazionale carattere il cui valore
è «vero» oppure «falso». Così, ad esempio, supponendo che VOCE e TESTO
siano i nomi simbolici di due variabili carattere entrambe di lunghezza lO, sono
corrette le seguenti istruzioni di controllo che coinvolgono espressioni relazionali carattere:
IF (TESTO.GT.VOCE) TESTO (l: 3) = 'ALB'IF (TESTO (3: 5).LT.VOCE (3: 5» GOTO lOIF (TESTO.EQ.' AUTOMOBILE') VOCE = 'DAvCORSA'IF (VOCE.NE.TESTO (l: 5) Il 'CARTA') VOCE = 'PENNA'
Per capire le modalità secondo le quali viene valutata un'espressione reiazionalecarattere, occorre tener presente che:
• l'ordinamento alfabetico delle lettere equivale ad un ordinamento in sensocrescente ovvero:
A<B<C< ... < X<Y<Z
• le cifre decimali sono ordinate in senso crescente:
0<1<2< ... <8<9
• l'insieme costituito dalle lettere dell'alfabeto e dalle cifre decimali deve essereordinato in uno dei modi seguenti:
0< I <2< ... <8<9<A<B< ... <Y<Z
A<B< ... <Y<Z<O< l < ... <8<9
la scelta tra questi due ordinamenti è lasciata al singolo sistema di calcolo;
• il carattere blank precede sia la lettera A che la cifra zero cioè blank < A eblank < O.
Altri caratteri diversi dalle lettere dell'alfabeto, dalle cifre decimali e dalla
spaziatura costituiscono un insieme il cui ordinamento non viene fissato dal
FORTRAN ma dal sistema di calcolo su cui si lavora. Nel prossimo paragrafo
vedremo come è possibile utilizzare mediante opportune funzioni intrinseche,l'ordinamento dei caratteri del sistema di codifica ASCII e rendere pertanto indi
pendente dall'elaboratore usato il risultato del confronto tra espressioni carattere.
Il confronto tra due operandi di tipo carattere avviene nel modo seguente:
• se i due operandi hanno lunghezza diversa, quello più corto viene allungatoaggiungendo caratteri blank alla sua destra;
: ~~ i
186187
• i due operandi vengono confrontati a partire dal loro carattere iniziale: è
«maggiore» l'operando che ha il carattere iniziale maggiore. Se i caratteri ini
ziali sono uguali il confronto tra i due operandi procede carattere per carattere
fino a che non si trovano due caratteri diversi: la relazione tra questi due carat-
i teri determina quella tra i due operandi;
\. due operandi sono uguali se sono costituiti da stringhe di caratteri uguali.
Esempio J2.23. Le relazioni tra stringhe di caratteri:
'GIANNI'.GT.'AGUZZI''MARIA'.GT.'MACCONI''GRAZIA'.GT.'GASPARO'
sono tutte vere. La veridicità della prima espressione è determinata dal1a rela
zione che lega le lettere iniziali dei due operandi, quella del1a seconda dalla
relazione che lega il terzo carattere dei due operandi e quella della terza dal1a
relazione che lega il secondo carattere dei due operandi.
E' ancora «vero» il risultato del1'espressione:
Esempio J2.25. Si vuoI scrivere un programma che, letta una stringa di 7 carat
teri alfabetici, permetta di stabilire se la lettera iniziale e quella finale della stringaprecedono M e quante volte compare nella stringa la lettera B.
CHARACTER * 7 VARREAD *, VARIF (VAR(I: 1).LT.'M'.AND.VAR(7: 7).LT.'M') THEN
PRINT -. 'LAVLETTERAvINIZIALEVPRECEDEvM'PRINT *, 'LAvLEITERA vFINALEvPRECEDEvM:
ELSE
PRINT -. 'LAVLETTERAvINIZIALEVNONvPRECEDEVMvOPPURE'PRINT *, 'LAvLETTERAvFINALEvNONvPRECEDEvM'
ENDIFNB =0DO IO 1=1,7IF (VAR(I: I).EQ.'B') NB = NB + I
IO CONTINUE
PRINT *, 'LAvLETTERAvBVCOMPARE', NB, 'vVOLTE'STOPEND
'GENNAIO vI986'.LT.'GENNAlO v1987'
LLT CIvMAGGlOv 1986', 'l vMAGGIO vI987')
12.7. Funzioni intrinseche per la manipolazione dei caratteri
Le funzioni LGE, LGT, LLE, LLT
Nel paragrafo precedente è stato osservato che è possibile confrontare tra loro
due stringhe di caratteri indipendentemente dal sistema di codifica usato dal sin
golo elaboratore. II FORTRAN prevede infatti quattro funzioni intrinseche LGE,
LGT, LLE, LLT ciascuna delle quali permette di confrontare due espressioni
carattere secondo l'ordinamento definito nel sistema di codifica ASCII. Queste
quattro funzioni operano su due argomenti ciascuno dei quali è costituito da una
espressione carattere di lunghezza arbitraria; il risultato di ciascuna funzione è
un valore logico che rappresenta il risultato del confronto tra i due argomentieseguito secondo il codice ASCII. Più precisamente:
Esempio J2.26. II valore dell'espressione:
Cl ~ c2
cl> c2Cl .ç c2
Cl < c2 ·
dà risultato vero se
dà risultato vero se
dà risultato vero se
dà risultato vero se
LGE (Cl' c2)
LGT (cl' c2)
LLE (Cl' c2)
LLT (Cl' c2)
'I vMAGGlOvI986'.LT.'1 vMAGGIO v1987'
CHARACTER * IO DATOREAD -. DATOIF(DATO(I :I).EQ.' A'.AND.DATO (IO:IO).EQ.'1') THEN
PRINT *, 'LAvSTRINGAvINIZIAvCONvA vE vTERMINAvCONvl'ELSE
PRINT -. 'CARATTEREvINIZIALEv', DATO(I:I)PRINT *, 'CARATTEREvFINALEv', DATO(10:10)
END IFSTOPEND
mentre dipende dal sistema usato il valore dell'espressione:
Esempio J2.24. Si vuoI scrivere un programma che, letta una stringa di IO carat
teri, permetta di stabilire se essa inizia con la lettera A e termina con la lettera I.Nel caso in cui questo non sia verificato, il programma deve stampare il carattere
iniziale e quello finale del1a stringa data in ingresso.
Vediamo ora alcuni esempi di programmi che prevedono confronti tra stringhe
di caratteri.
in quanto il FORTRAN non specifica quale sia l'ordinamento tra lettereecifre.
188
è «falso» in quanto nel codice ASCII l'insieme delle cifre decimali precede quello
delle lettere dell'alfabeto e quindi, in particolare, I> l.
La funzione INDEX
La funzione intrinseca INDEX permette di localizzare in una stringa di carat
teri il punto in cui compare un'altra stringa di caratteri. La funzione lNDEX ha
due argomenti di tipo carattere: il primo, sI' identifica la stringa che deve essere
analizzata, il secondo, s2 ' indica la stringa che deve essere localizzata dentro sI'
II risultato della funzione INDEX (SI' s2) è un valore intero che indica la posizio
ne del carattere iniziale di s2 nella stringa SI' Se s2 compare più di una volta in
SI il risultato di INDEX (SI' s2) è la posizione del carattere iniziale della prima
occorrenza di s2 in SI . Il risultato di INDEX (sI' s2) è zero se s2 non compare inSI oppure se la lunghezza di s2 è maggiore di quella di SI'
Pertanto il risultato di:
INDEX ('IL'I7NOME'I7DELLA 'I7ROSA', 'NOME')
è 4 perché la stringa NOME si trova nella stringa IL '17 NOME '17 DELLA '17 ROSA a
partire dal quarto carattere. Analogamente, 12 è il risultato di:
INDEX ('IL '17 NOME '17 DELLA '17 ROSA', 'LA')
189"
PARAMETER (LLIN = 70, LUN = 4)CHARACTER LINEA * (LLIN), ART * (LUN)INTEGER POSNUM=OREAD -. LINEAART = ''I7UN'I7'LOC= lDO lO I = l, LLIN/LUNPOS = INDEX(LINEA(LOC :), ART)IF (POS.EQ.O) GO TO 20LOC = POS + LUN+ LOC- 1NUM = NUM + lPRINT *, ART, 'COMPARE'I7NELLA'I7POSIZIONE'I7', (POS + LOC- l)
lO CONTINUE20 PRINT *, 'NUMER0'l7D1'170CCORRENZE'I7D1'17', ART, NUM
STOPEND
11 multato dell'espressione lNDEX (LINEA (LOC:), ART) indica la DosizioJ1e
di ART nella sottostringa LINEA (LOC:). Così quando LOC vale I, POS indica
J;pc;sizione in LINEA-della prima occorrenza di ART. Successivamente il conte
nuto di LOC viene modificato in modo da analizzare la stringa LINEA a partire
dalla posizione LOC che segue immediatamente quella dell'ultimo carattere di
ART. Supponendo che la stringa memorizzata in LINEA sia:
UNA DONNA VIDE UN GATIO CHE SALTAV A SUL PRATO DA UN RAMO DI UN ALBERO
la successione di valori delle variabili LOC e POS è la seguente:
,I
La funzione ICHAR ha come argomento un'espressione carattere di lunghezza
uno (ovvero un singolo carattere) e dà come risultato un valore intero che rappre
senta la posizione del carattere nel sistema di codifica usato dall'elaboratore. 11FORTRAN specifica che se un sistema prevede la codifica di n caratteri il risultato
di ICHAR dovrà essere un intero compreso tra zero ed (n - I). Evidentemente,
l'argomento di lCHAR deve essere un carattere rappresentabile sul sistema usato.
La funzione CHAR ha come argomento una espressione intera, i, il cui valore
deve essere compreso tra zero ed (n - l) essendo n il numero di caratteri codifi
cati sull'elaboratore u
Le funzioni ICHAR, CHAR e LEN
mentre zero è il risultato di:
INDEX ('IL '17 NOME 'I7DELLA '17 ROSA', 'ROSSA')
INDEX ('NOME', 'IL '17 NOME 'I7DELLA 'I7ROSA')
La funzione INDEX può essere utilizza la ad esempio per risolvere il problema
di determinare il numero totale di occorrenze di una data stringa in una più lunga
e, in generale, per determinare il numero di volte che una certa espressione lessicale è usata in un testo.
Esempio 12.27. Si vuoi scrivere un programma che permetta di calcolare il nume
ro di volte che l'articolo indeterminativo UN compare sulla riga di una pagina di
un libro. Si vogliono inoltre individuare le posizioni delle singole occorrenze del
l'articolo UN nella riga che supporremo composta da 70 caratteri.
Indicata con LINEA la variabile carattere che contiene la riga da esaminare e
con NUM il numero totale di occorrenze della stringa' '17 UN '17' in LINEA, un
programma che permetta di risolvere il problema è il seguente:
Valore di
LOC
l
19
53
64
Caratteri analizzatiin LINEA
dal primo al 70-mo
dal 19-mo al 70-mo
dal 53-mo al 70-mo
dal 63-mo al 70-mo
Valore diPOS
15
49
60
O
T190
191
Il risultato di CHAR (i) è il carattere corrispondente alla i-ma posizione nel sistema di codifica usato. Evidentemente se I è un intero tale che O ,ç I ,ç n - l edX è un carattere codificato si ha che:
Il FORTRAN prevede per la elaborazione delle informazioni carattere un'altrafunzione intrinseca, LEN(c), il cui risultato è la lunghezza dell'espressione carat
tere che costituisce il suo argomento. L'utilizzazione di questa funzione verràesemplificata nel cap. 15.
Esempio 12.28. Si vuoi scrivere un programma che permetta di sostituire ad
ogni lettera di una stringa di caratteri quella che la segue nell'alfabeto e lasci inalterati i caratteri non alfabetici. La lettera Z deve essere sostituita dalla A.
Per risolvere questo problema si può usare il seguente algoritmo:
I. Leggi: la stringa
2. ripeti per ogni carattere della stringa:
2.1. se il carattere è compreso tra A ed Y
allora: sostituiscilo con la lettera successiva;
altrimenti: se il carattere è la lettera Z:
allora: sostituiscilo con la lettera A;
altrimenti: lascia il carattere inalterato
in corrispondenza a ciascuna delle seguenti frasi di assegnazione:
AUGURI = 'BUONvNATALEvEvFELICEvANNOvNUOVO'AUGURI = 'BUONvI987'
AUGURI = 'TANTIvAUGURlvDIvBUONvCOMPLEANNO'
Indicare il contenuto delle sottostringhe
AUGURI (: 4)
AUGURI (5 : 12)
AUGURI (7 : 12)
AUGURI (16 : 17)
AUGURI (21 : 26)
AUGURI (27 :)
scrivere le frasi di assegnazione che permettono di:
a) assegnare a PRIMO la stringa di caratteri che si ottiene concatenandoi valori dei tre elementi del vettore LISTA:
b) sostituire all'ultimo carattere di PRIMO la lettera W;
c) sostituire il contenuto del primo elemento di LISTA con i primi cinquecaratteri di PRIMO;
d) sostituire il secondo carattere del secondo elemento di LISTA con il numero 8.
n""" L
Esercizi
12.1 Indicare la lunghezza delle seguen ti costanti carattere:a) 'LAvVOLPEvARGENTATA'b) 'COSAv c"E"?' ìÒr
c) 'vQUESTA vAUTOMOBILE vE" vVELOCEv , ~
d) 'vROSSO, BIANCO. VERDEv I C,e) 'vvv'
12.2 Supponiamo che un programma contenga la seguente frase di specificazione:
CHARACTER * 31 AUGURI
12.3 Supponendo che un programma contenga la frase
CHARACfER * 5 LISTA (3), PRIMO * 15
12.4 Scrivere un programma che permetta dI copiare in ordine inverso in una va
riabile carattere B i caratteri di un'altra variabile A, ovvero di sostituire l'ul
timo carattere di B con il primo di A. il penultimo con il secondo e così via.
ha lo stesso valore di X
ha lo stesso valore di I
CHAR (lCHAR (X))
ICHAR (CHAR (I)
3. stop.
Nel programma seguente indichiamo con STR la stringa data e con L la sualunghezza che supporremo al più uguale ad 80.
PROGRAM ROTAZCHARACTER STR * 80, CAR, SREAD *, LREAD -. STRDO IO I=I,LCAR = STR (I : I)IF (A'.LE.CAR.AND.CAR.LE.'Y') THEN
S = CHAR(lCHAR (CAR) + I)ELSE IF (CAR.EQ.'Z') THEN
S= 'A'ELSE
S=CARENDIFSTR (I: I) = S
IO CONTINUEPRINT *, STRSTOPEND
riI
!.\
!!
I
192
12.5 Scrivere un programma che stampi in ordine alfabetico i cognomi di 25alunni di una classe.
12.6 Scrivere un programma che, data una stringa di 80 caratteri, ne costruiscaun'altra ottenuta dalla prima sopprimendo le spaziature.
12.7 Scrivere un programma che legga N righe di un testo ciascuna delle quali
è composta da 80 caratteri e contiene soltanto parole complete. Il program
ma deve contare il numero di parole contenuto nelle N righe, il numero di
occorrenze della lettera A e di una stringa assegnata STRING.
Supponendo N = 7 e STRING = 'MODELLO', eseguire il programma avendo come dato il testo seguente:
«Come è ben noto la ricerca della soluzione di molti problemi può esserespesso così schematizzata:
- si sostituisce al problema reale un modello matematico che conserva lecaratteristiche essenziali del problema di partenza;
- si sceglie il metodo per risolvere il modello in esame;
- si interpreta la soluzione trovata in termini del problema di partenza perverificarne la validità».
l
13Operazioni di ingresso / uscita con formato
13.1. Alcune considerazioni sulle frasi di ingresso/uscita guidate dalla lista
In generale, un'istruzione di ingresso/uscita deve contenere le seguenti indi
cazioni: la direzione in cui avviene la trasmissione di informazioni, dall'esternoverso la memoria (ingresso) o dalla memoria verso l'esterno (uscita); il mezzo di
ingresso/uscita da~-;e; la lista delle locazioni di memoria interessate alla
trasmissione delle informazioni e le modalità secondo le quali tali informazioni
devono essere rappresentate all'esterno. Così, ad esempio, nelle frasi di ingres
so/uscita guidate dalla lista
READ *, A, N
PRINT *, A, N
le parole chiave READ e PRINT indicano il tipo di operazione, 11 mezzo usato non
è esplicitamente indicato ed è quello standard, la lista A, N indica le locazioni di
memoria di cui si deve trasmettere il contenuto ed infine l'asterisco indica che le
modalità di rappresentazione esterna dei valori trasmessi dipendono dal sistema e
dalla lista (in questo senso va infatti interpretata la denominazione «guidate dalla
lista»).
Come si è accennato nel cap. 8, le frasi READ * e PRINT * sono molto semplici da usare ma poco flessibili perché non consentono di scegliere il modo in
cui i dati devono essere disposti sul mezzo di ingresso/uscita; ciò può implicare,
in un'operazione di lettura, l'impossibilità di usare insiemi di dati già predisposti
perché questi non possono essere interpretati nel modo desiderato.
Esempio 13.1. Consideriamo il seguente problema. supponendo che l'unità di
ingresso standard sia il lettore di schede. Per ogni dipendente di un'azienda si
ha una scheda già predisposta su cui sono perforati anno di nascita, nome e cognome, senza alcuna spaziatura fra il primo dato e il nome ma con uno spazio
fra questo e il cognome. Si vogliono leggere le schede una per volta memorizzando
l'anno di nascita in una variabile intera, NASC, ed il nome e cognome in una va
riabile carattere, NOME, di lunghezza 30. La frase di lettura
194
READ., NASC, NOME
non può essere usata allo scopo desiderato. Infatti, supponendo ad esempio cheuna scheda contenga i dati:
1928FRANCA GENSINI
essa viene così interpretata al momento dell'esecuzione della frase di lettura:
il primo dato è 1928FRANCA in quanto inizia con il primo carattere non blanke termina con il carattere che precede il blank successivo; il secondo dato è GEN
SINI. Siccome il primo dato non è una costante intera e il secondo dato non è
una costante carattere, si crea una situazione di errore che impedisce la prosecuzione del programma.
Come si vedrà nel corso del presente capitolo, in FORTRAN si possono usare
istruzioni di ingresso/uscita più generali di quelle guidate dalla lista, nelle quali è
possibile indicare esplicitamente una specificazione di formato, ossia una descrizio
ne del modo in cui devono essere forniti e interpretati i dati (se si tratta di una
istruzione di ingresso) o in cui devono essere visualizzati i risultati (se si tratta di
un'istruzione di uscita). Le istruzioni di ingresso/uscita in F77 sono molto più
flessibili di quanto non lo fossero in F66. Le innovazioni portate rispetto allo
standard precedente sono sostanziali e numerose e pertanto, per rendere più sem
plice l'esposizione di questo capitolo, si tralascerà di sottolinearle rimandando al
l'appendice A2 per un riepilogo finale.
Nel seguito la sigla I/O (lnput/Output) potrà sostituire l'espressione ingresso/
uscita ed il termine record indicherà un insieme di caratteri rappresentato su un
qualsiasi supporto fisico quale, ad esempio, una riga di stampa, una scheda per!~
rata, una linea su video etc.
13.2. Specificazioni di formato
Le informazioni trasmesse durante un'operazione di I/O sono rappresentate
all'esterno della memoria su records. La struttura di tali records può essere descrit
ta mediante una specificazrone di formato che, in particolare, individua una sud
divisione di ciascun record in uno o più campi, ossia gruppi di caratteri ognuno
dei quali contiene un singolo dato; l'ampiezzadi un campo è il numero di carat
teri che lo compongono. La specificazione di formato descrive completamente
il modo in cui ogni dato deve essere scritto nel campo che gli è destinato e può
inoltre contenere altre informazioni utili per l'interpretazione dei records.
Una specificazione dì formato ha la forma seguente:
r195
in cui ciascun e j può essere del tipo:
• r dr
• dor
• r sfdove:- r è uru;ontatoredi ripetizione che, se presente, deve essere una costante in-
tera positiva senza segno; r può essere omesso se uguale ad I;- d è un descrittore npettbile ossia una stringa di caratteri che specifica l'arnpie;za del campo su ~ui deve essere rappresentata un'informazione, il tipo di
informazione ed il modo in cui essa deve essere scritta sul record;- d è un descrittorenon.ripetibile ossia una stringa di caratteri che fornisce alor ..u u_ . • •
compilatore particolari informazioni sulla composizione e l'interpretazione dì un
record;- sf è a sua volta una specifi~aziQnedif!!!J11 ato.
Ciascun e. della forma rdr equivale ad r descrittori dr separati da virgole;l
così per esempio,
(et' 2 dr' e3 ) equivale a (et, dr' dr' e 3)
Ciascun e. della forma rSf equivale ad una specificazione di formato costituitaI .
da r ripetizioni separate da virgole della specificazione di formato sf privata delle
parentesi; così, ad esempio, se sf indica la specificazione (e" ez),
(e" 2 sf' e3) equivale a (e,. (e l , ez' e" ez), e3)
In fig. 13.1 è riportato l'elenco dei descrittori ripetibili previsti in F77 che pos
sono essere suddivisi in descrittori di tipo numerico, carattere e logico in base
al tipo di informazione rappresenta bile nel campo da essi descritto. In ogni
Descrittori ripetibili Descrittori ripetibili Descrittori ripetibilidi tipo numerico di tipo logico di tipo carattere
Iw Lw AIW.m AwFW.dEW.dEw.dEcDW.dGW.dGw.dEc
Figura 13.1. Descrittori ripetibili in F77.
196197
descrittore, il simbolo W rappresenta una costante intera positiva senza segno che
indica l'ampiezza del campo individuato dal descrittore mentre la lettera I, F, E,
D, G, A, L indica il tipo di informazione contenuta nel campo (numerico per
I, F, E, D, G, carattere per A, logico per L). II significato dei simboli d, ed m
(costanti intere non negative e senza segno) e di c (costante intera positiva e
senza segno) sarà chiarito nei paragrafi successivi.
In fig. 13.2 è riportato l'elenco dei descrittori non ripetibili previsti in F77;
nella stessa figura accanto ad ogni descrittore viene brevemente riassunto il suo
significato.
Come verrà ulteriormente specificato nel § 13.9, ogni elemento della lista in
una frase di I/O nella quale è indicata una specificazione di formato è associato ad
un descrittore ripetibile; il descrittore stabilisce in che modo deve avvenire la
conversione del dato dalla sua rappresentazione interna in memoria come valore
dell'elemento della lista di l/O alla sua rappresentazione esterna sul record, o
viceversa. I descrittori non ripeti bili presenti nella specificazione di formato non
sono invece associati ad alcun elemento del1a lista di I/O.
Esempio 13.2. Sono esempi di specificazioni di formato i seguenti:
13.3. Rappresentazione dei dati numerici sui records di I/O
I numeri sono rappresentati sui records di I/O in base dieci mentre sono rappre
sentati in memoria nel sistema di numerazione usato dall'elaboratore. Pertanto
l'ingresso/uscita di un dato numerico implica l'esecuzione di un algoritmo di
conversione da un sistema di numerazione ad un altro e l'eventuale troncamento
o arrotondamento del1a mantissa per i numeri reali (cfr. cap. 3).
Esponiamo in questo paragrafo alcune regole generali riguardanti la rappresen
tazione esterna dei dati numerici sui records di l/O.
• In ingresso i caratteri blank nelle prime posizioni di un campo destinato al1a
rappresentazione di un dato numerico non sono significativi, mentre un campo
costituito da soli caratteri blank viene interpretato come zero. Gli eventuali ca-
~taITenoTànK-presenti nel campo dopo il primo carattere non blank possono essere
interpretati come zero oppure ignorati e l'interpretazione dipende, per i mezzi di
I/O standard, dal sistema di calcolo. Negli esempi che seguono, quando non sia
diversamente specificato, adotteremo la convenzione che tali caratteri blank
vengano interpretati come zero, coerentemente con la regola esistente al riguardo
in F66. Va osservato che in F77 è possibile stabilire nel1a specificazione di forma
to l'interpretazione di tali caratteri sia per mezzi di I/O standard che per mezzi
non standard utilizzando i descrittori non ripetibili BN e BZ (cfr. § 13.15).
• In uscita i numeri vengono sempre scritti nelle posizioni più a destra del campo
loro riservato e sono eventualmente preceduti da caratteri blank : il segno precede
immediatamente il primo carattere non blank. II segno + è considerato in F77
opzionale e la sua presenza nei campi numerici in uscita dipende dal sistema; si
può comunque imporre una convenzione specifica al riguardo usando i descrit
tori non ripetibili S, SP, SS (cfr. § 13.15). Negli esempi che seguono adotteremo
la convenzione di omettere tale segno.
• In uscita un campo destinato al1a rappresentazione di un numero viene riem
pito di asterischi se, tolti i caratteri opzionali, il dato non può essere rappre
sentato secondo le modalità dettate dal descrittore. Così. ad esempio, un campo
di ampiezza 2 destinato a contenere un numero intero viene riempito di asteri
schi se il dato da rappresentare è - 12 che richiede tre caratteri; se però il dato da
(12,12, F5.3)
(EI3.6, F5.1, F5.1, F5.1)
«5X, EI3.6, 5X, EI3.6»
(IX, 13, (15, F8.1, 15, F8.1, 15, F8.1»
fine di un record
inserimento della stringahl ... hn su un record di uscita
salto di n caratteri
descrittori di tabulazione
termine dell'operazione se la lista di I/O è esaurita
interpretazione dei caratteri blank nei campinumerici su records di ingresso
gestione del segno + nei campi numericinei records di uscita
fattore di scala per valori numerici
Figura 13.2. Descrittori non ripetibili in F77.
nX
TnTLnTRn
BNBl
sP
sSPSS
(15, F8.1)
(A4)
(v SPECIFICAZIONEvDlvFORMATO')
(3X,'H =', D22.15,'N =', 14)
(212, F5.3) equivalente a
(EI3.6,3 F5.l) equivalente a
(2(5X, EI3.6» equivalente a
(IX, 13,3(15, F8.1» equivalente a
r198 J99
rappresentare è + 12, allora il campo sul record di uscita è riempito con la stringa
12 ed il segno + non viene riportato, qualunque sia la convenzione in atto al ri
guardo.
13.4. 1\ descrittore Iw per dati di tipo intero
Il descrittore Iw individua un campo destinato alla rappresentazione di un dato
intero. Sia in ingresso che in uscita il dato è rappresentato sul record come costan
te FORTRAN intera.
viene interpretato secondo la specificazione di formato precedente. i dati lettisono i numeri 121, 1235, 25000, O. 12549.
Se lo stesso record viene interpretato secondo la specificazione di formato
(1112)
i dati letti sono i numeri 12. II. 23, 52, 50, O, O, O, 1,25.49.
Osserviamo che sul record non c'è nessun carattere di separazione fra un dato
e l'altro: la suddivisione in campi dedotta dalla specificazione di formato è sufficiente per individuare la fine di un dato e l'inizio del successivo.
vv123 oppure v+ 123 oppure +v123
Esempio 13.3. Su un record di ingresso un campo è individuato dal descrittore
15. Se il contenuto del campo è
esso viene interpretato come il numero intero 123. Se invece il contenuto del
campo è
Esempio 13.4. Indichiamo qui di seguito come II numero 333 puo essere rappre
sentato su records di ingresso o di uscita in campi individuati da alcuni descrit
tori lw.
13.5. I descrittori Fw.d, Ew.d, DW.d per dati di tipo reale e doppia precisione
Un descrittore Fw.d, Ew.D o Dw.d individua un campo di ampiezza w desti
nato alla rappresentazione esterna di un numero reale. I descrittori Fw.d, Ew.d,
Dw.d, insieme a Ew.dEc, GW.d e Gw.dEc (cfr. § 13.15) saranno indicati con iltermine descrittori reali.
I descrittori reali in ingresso
In ingresso i descrittori reali sono tutti equivalenti : il dato può essere rappre
sentato, nel campo di ampiezza w, nella forma di costante FORTRAN intera,
reale o doppia precisione. Se il dato è nella forma di costante reale con espo
nente, l'esponente può essere scritto come una costante intera con segno non
preceduta dalla lettera E oppure D. Se nel campo è presente il punto decimale.allora il l'alare di d specificato nel descrittore non ha alcun significato; in caso
contrario, il dato viene interpretato come se fosse presente un punto decimale
immediatamente precedente le d cifre più a destra nella stringa di caratteri cherappresenta il numero, escluso l'esponente.
Esempio 13.6. Riportiamo qui di seguito \'interpretazione che viene data del
.contenuto di un campo di ampiezza 5 in corrispondenza a diversi descrittori, reali.
Campo Descrittore Interpretazione
uscita
**
333
v333
ingresso
333
v333
impossibile
(13,14,315)
descri ttore
1314
12
Esempio 13.5. La specificazione di formato
vl23v oppure + 123v
esso viene interpretato come il numero intero 123 o 1230 a seconda della con
venzione in atto sull'interpretazione dei caratteri blank.
, I
Ii,l'
Il
III
è equivalente a
(13,14,15,15,15)
e descrive cinque campi consecutivi destinati alla rappresentazione di dati interi.
Il primo campo ha ampiezza 3, il secondo 4 e gli ultimi tre hanno tutti ampiezza5. Se il record di ingresso
121123525000 vvvv v 12549
vv2.5
2 .5vv
- 2 .5 v
. 2EO I
.7E-3
3 . 1+4
\vv3 vv
F5.0
F5.2
F5.4
F5.2
E5.l
05.1F5.2
2.5
2.5
- 2.5
2.
0.0007
31000.
3. se ogni spazio equivale ad uno zero oppure
0.03 se gli spazi sono ignorati.
200 201
dove lo zero prima del punto decimale può non essere presente, e dove:• al'" ad sono le prime d cifre della mantissa del numero espresso in base
dieci, e la cifra ad è ottenuta per arrotondamento;
• exp è una stringa di 4 caratteri che contiene la caratteristica b del numero
espresso in base dieci. In fig. 13.3 dove bI' b2, b3 rappresentano le cifre di b, si
riportano le forme di exp che si possono avere con il descrittore EW.d quando b
è compreso in valore assoluto fra O e 999; la scelta tra la forma in cui compare la
lettera E e l'altra forma dipende dal sistema. Se si usa il descrittore DW.d sono
possibili, a scelta del sistema, tutte le forme previste in fig. 13.3 e una terza forma
in cui la lettera D sostituisce la lettera E.
del punto decimale, resta disponibile un solo carattere per la parte intera del nu
mero che invece è costituita dalle due cifre I e 2. Si osservi inoltre che medianteil descrittore F5.3 il numero 0.0004 viene rappresentato come zero mentre ilvalore 0.0005 è rappresentato come .00 l. Nel primo caso quindi il descrittore
non permette una corretta rappresentazione esterna del dato il cui valore sembraessere zero, mentre nel secondo caso si ottiene una rappresentazione dello stesso
ordine di grandezza del valore in memoria.
I descrittori Ew.J e DW.d in uscita
In un campo individuato dal descrittore FW.d su un record di uscita sono rap
presentati come zero tutti i numeri reali che sono, in valore assoluto, minori di
0.5 x 10- d. Pertanto non conviene usare tale descrittore se si desidera che la
rappresentazione esterna di qualunque numero reale contenga informazioni sul
suo ordine di grandezza. In tal caso si possono usare i descrittori EW.d e Dw.d,
con w ~ d + 7, ai quali corrisponde una rappresentazione esterna della forma
Nell'ultimo caso si vede come, in corrispondenza dello stesso descrittore reale,
una stessa stringa di caratteri senza il punto decimale può essere interpretata in
modi diversi. Per evitare interpretazioni diverse da quella desiderata, è consiglia
bile inserire sempre il punto decimale nei dati reali.
AI momento della sua acquisizione, il dato scritto nel campo in ingresso viene
letto e convertito nel sistema di numerazione usato dall'elaboratore' la sua rap-I . '
( . presentazione interna sarà in precisione semplice o doppia coerentemente con iii
l I \ tipo della locazione di memoria in cui esso deve essere memorizzato, e indipen~
dentemente dal numero di cifre decimali con cui esso è rappresentato sul record.
l descrittori reali in uscita
!II uscita i descrittori reali non sono fra loro equivqlenti in quanto definisco
no modalità diverse di rappresentazione esterna di un numero reale nel campo
di ampiezza w. In ogni caso, indipendentemente dal tipo di rappresentazione
interna del dato (semplice o doppia precisione), la sua rappresentazione esternacontiene d cifre dopo il punto decimale di cui l'ultima ottenuta per arrotondamento.
II descrittore Fw.d in uscita
Il descrittore Fw.d produce in uscita la rappresentazione del dato nella for
ma di costante reale FORTRAN senza esponente con d cifre dopo il punto deci
male. Se il valore assoluto del dato è minore di l, la presenza o meno di uno zero
prima del punto decimale dipende dalla convenzione usata dal sistema di calcolo.Nel seguito adotteremo la convenzione di omettere questo zero.
Esempio 11.7. Riportiamo la rappresentazione esterna di arcuru numeri reali incorrispondenza a diversi descrittori Fw.d
(13.1 ) ± O.al ... ad exp
Rappresentazione Descrittore Rappresentazioneinterna esterna
fI (- 12.388) F6.3 ******fI (T2.388) F6.3 12.388fI (- 786.3346) FIO.3 V'V'-786.335fI (- 786.3346) F5.0 -786.fI (0.0004) F5.3 V'.OOOfl (0.0005) F5.3 V'.001
Si osservi che nel primo caso il campo, di ampiezza 6, viene riempito di aste
rischi; infatti, essendo d = 3 ed essendo obbligatoria la presenza del segno - e
b exp
b=O E +00 oppure +000
l <lbl~9 E ± Ob, oppure ± OOb l
9 <Ibl ~99 E ± bi b2 oppure ± os,b2
99 <I bl~999 ± bi b2 b3
Figura 13.3. Forme di exp nella rappresentazione esterna ± O.al ... ad expcorrispondente a Ew.d.
Osserviamo che i numeri reali la cui caratteristica b e, in valore assoluto, mag
giore di 999 non possono essere rappresentati mediante i descrittori EW.d e DW.d
ma solo mediante opportuni descrittori EW.dEc e Dw.dEc (cfr. § 13.15).
202 r 203
Esempio 13.8. Riportiamo la rappresentazione esterna prodotta da alcuni descrit
tori EW.d e DW.d in corrispondenza di determinati valori interni. Nei primi due
casi indichiamo tutte le possibilità, negli altri soltanto una.
I descrittori EW.d e Dw.d consentono di rappresentare in uscita i numeri reali
con un qualunque numero di cifre di mantissa. Evidentemente è sufficiente fissare
d ,ç t quando è noto che un dato non può avere più di t cifre di mantissa esatte;
una diversa scelta di d provocherebbe la rappresentazione di cifre non attendibili
in quanto sicuramente affette da errore.
'ii Si osservi che i descrittori Ew.d e Dw.d possono essere usati in F77indif~e~l\
Il rentemente qualunque sia la rappresentazione interna del dato. Se, nel sistema~con'cui si lavora, il descrittore Dw.dproduce una rappresentazione esterna in cui com
pare la lettera D, allora esso può essere usato quando si vuole mettere in evidenza,
che il dato riprodotto sal record era rappresentato internamente in doppia precisione.
i
l'; I
Rappresentazione
interna
Il r- 786.5936)
Il (- 786.5(36)
Il (0.0001)
Il (0.0009)
Il (- 10- 8)
Il (2 )( 1015)
Descrittore
E13.6
010.3
EIO.3
EIO.3
011.4
011.4
Rappresentazione
esterna
- 0.786594E + 03 opp. - 0.786594 + 003
- 0.7870 + 03 opp. - 0.787E + 03 opp. 0.787 + 003
v O.lOOE - 03
vO.900E - 03
- 0.10000 - 07
VO.2000D + 16
Essa individua due campi di ampiezza 13 destinati alla rappresentazione di due
numeri reali. Secondo tale specificazione Il numero complesso 3.35 - li può
essere rappresentato nel modo seguente
",,0.335000E + al - 0.200000E + al
mentre il numero complesso + 7i, con parte reale uguale a zero, è rappresentato.ad esempio, da
""O.OOOOOOE + 00 ""0.700000E + al
Osserviamo che la specificazione di formato e i records precedenti potrebbero
anche riguardare l'ingresso/uscita di due numeri reali; infatti l'interpretazione
data ai due valori trasmessi è diversa a seconda se i due descrittori reali sono asso
ciati. tramite la lista di 110. a due locazioni reali o ad una complessa.
13.7. I descrittori ripetibili per dati di tipo carattere
Per n/o di stringhe di caratteri si può usare il descrittore ripetibile Aw, dove
w rappresenta, come al solito, l'ampiezza del campo. Le modalità di rappresenta
zione esterna del dato dipendono dalla relazione che sussiste fra we la lunghezza
Q dell'elemento della lista di 110 associato al descrittore.
Il descrittore Aw in uscita
In uscita, se w ;;;. Q, la stringa di Qcaratteri viene posta nelle Qposizioni più a de
stra del campo preceduta da w-Q caratteri blank , mentre se w < Qnel campo ven
gono riprodotti i primi w caratteri della stringa.
Esempio 13.10. Sia CANE ""LUPO la stringa di caratteri che si vuole riprodurre
su un record di uscita: essa viene rappresentata tutta o in parte, a seconda del descrittore usato:
Il descrittore Aw in ingresso
In ingresso, se w ;;;. Q vengono convertiti e memorizzati gli Q caratteri più a
destra del campo; se invece è w < Q la stringa di caratteri presente nel campo, se
guita da Q - w caratteri blank, viene memorizzata nella locazione corrispondente.
13.6. I descrittori ripetibili per dati di tipo complesso
Per la rappresentazione di un numero complesso su un record di 110 occorrono
due campi individuati da due descrittori reali non necessariamente uguali fra loro;
il primo campo è riservato alla rappresentazione esterna della parte reale del nu
mero, il secondo a quella della parte immaginaria. Nella specificazione di formato
i due descrittori possono eventualmente essere separati da uno o più descrittori
non ripetibili. Da quanto detto segue che un numero complesso viene rappre
sentato su un record di IlO come una coppia di numeri reali; ricordiamo a tale
proposito che quando si usa la frase di ingresso guidata dalla lista, i numeri com
pIessi devono essere fomiti sotto forma di costante FORTRAN complessa, ossia
come coppia di costanti reali, separate da una virgola e racchiuse fra parentesi.
Esempio 13.9. Sia data la seguente specificazione di formato (2EI3.6J.
Descrittore
A4
A5
A9
Al2
Rappresentazione
CANE
CANE""
CANE ""LUPO
""""""CANE""LUPO
204
Esempio 13.11. Sia MESE una variabile carattere di lunghezza g, in cui si deve
memorizzare la stringa di caratteri presente in un campo individuato da un descrit
tore Aw. Gli esempi seguenti mostrano l'effetto che si ottiene in corrispondenza
ad alcuni descrittori e campi in ingresso.
205
destinati alla rappresentazione di dati di tipo carattere e non hanno ampiezz~
presrabnua, mentre gli altri sono dedicati alla rappresentazione di numeri interi
ed hanno ampiezza 3. 11 record
PER 'V N = 125 'V K v V A LE : V'V 5 'V E'VM 'V VA LE: - 12
Descrittore Campo in ingresso
A8 GENNAIO v
A7 GENNAIO
A9 GENNAIOvv
Stringa memorizzata in MESE
GENNAIO v
GENNAIOv
ENNAIOvv
corrisponde alla specificazione data: il primo, il terzo ed il quinto campo hanno
in questo caso ampiezze rispettive 6, 8, IO. Anche il record
RIGA 'V'V l 'V COLONNA 'V'V IPIANO 'V'V l
E' evidente che quando w > Q, il dato in ingresso deve essere «allineato a de
stra» nel campo per evitare che vadano «persi» nella lettura caratteri significativi.
Inoltre si può osservare che il valore assegnato a MESE nell'ultimo caso è diverso
da quello che le verrebbe attribuito con la frase di assegnazione
MESE = 'GENNAIO v"/
Tale frase infatti provocherebbe il troncamento a destra della stringa
'GENNAIOv'V' e la memorizzazione in MESE del valore 'GENNAIO 'V'.
fii
corrisponde alla specificazione data, e in questo caso il primo, il terzo ed il quinto
campo hanno ampiezze 4,8,5.
!Da quanto detto segue che quando un record viene letto o scritto sotto il con
tr~.,di un~s-p,ecifica~ion.. e di formato un dato di tipo carattere viene rappresentato su di esso senza gli apici delimitatori che caratterizzano le costanti carattere;
ric~~i~mo che tali apici sono obbligatori se il record viene letto con una frase
READ*.---Come si è messo in evidenza in questo esempio, la lettura di dati di tipo carat
tere sotto il controllo del descrittore A w può non essere equivalente all'assegna
zione mentre tale equivalenza sussiste sempre quando la lettura è guidata dalla
lista (cfr. cap. 12). D'altra parte, la regola seguita nella lettura di dati di tipo
carattere è coerente con il fatto che in uscita essi vengono riprodotti nelle posi
zioni più a destra del campo loro riservato.
II descrittore A
Per l'I/O di dati di tipo carattere si può usare anche il descrittore A in cui.non
compare l'ampiezza del campo; in questo caso il campo risulta di ampiezza Q,
dove Q è la lunghezza dell'elemento della lista di I/O di cui si tr;~metteil vàlore.11 descnttore A può essere molto utile per l'uscita di dati di tipo carattere, il
cui valore viene riprodotto per intero sul record di uscita; d'altra parte questo
i~ descrittore va usato con molta precauzione in specificazioni di formato relative
~ a frasi di ingresso.
Esempio 13.1 :l. La specificazione di formato
(3 (A, 13»
equivale a
(A. 13, A, 13, A, 13)
e descrive un record costituito da sei campi: il primo, il terzo ed il quinto sono
13.8. Istruzioni di ingresso/uscita con formato relative ai mezzi standard
Le più semplici frasi di I/O con formato relative ai mezzi standard hanno la
forma seguente:
READ f, lista-di-ingresso
PRINT f, lista-di-uscita
dove:
• READ, PRINT, lista-di-ingresso e lista-di-uscita hanno lo stesso significato
visto nei capitoli precedenti;
• f è un identificatore di formato che può essere:
- un * (in questo caso la frase è guidata dalla lista);
- l'etichetta di una frase FORMAT presente nella stessa unità di programma in
cui compare la frase di I/O;
- un'espressione carattere;
- un nome di variabile dimensionata carattere.
Istruzione FORMAT
L'istruzione FORMAT è una frase non eseguibile che ha la forma
n FORMAT SI
dove:
'd,
I
,
206
• FORMAT è la parola chiave che identifica la frase;• n è l'etichetta, obbligatoria, della frase;
• sf è una specificazione di formato che risulta associata a tutte le istruzionidi ingresso/uscita della stessa unità di programma in cui figura n come identificatore di formato.
Esempio 13.13. Con la coppia di istruzioni
READ 150, N, M. A, B150 FORMAT (215, 2FI0.0)
si associa alla frase di lettura READ la specificazione di formato (215, 2F l 0.0),secondo la quale i valori da assegnare a N, M, A, B devono essere forniti su un
record secondo le modalità imposte dai descrittori 15 per i primi due e F 10.0 pergli ultimi due.
Se la stessa frase FORMA T è associata alla frase
PRINT 150, N, M, A, B
la specificazione di formato in essa contenuta descrive la struttura del record, sulmezzo di uscita standard, su cui verranno rappresentati i valori di N, M, A, B.
E' importante osservare che nella stessa unità di programma più frasi di 110, possono fare riferimento ad una stessa istruzione FORMAT e che u~';' frase.
" FORM~T può s.tare in qualunque punto dell'unità di programma (cfr. appendìce] \Il A3); di solito SI usa raggruppare tutte le istruzioni FORMAT prima della END ii
in modo da migliorare la leggibilità dell'unità di programma.'i
Esempio 13.14. Nel seguente programma la frase READ e la frase PRINT fannoriferimento alla stessa frase FORMAT, di etichetta 100, che contiene la specificazione di formato (2EI3.6).
READ 100, A, BA=A+1.B = B - 5.PRINT 100, A, BSTOP
100 FORMAT (2 EI3.6)END
Se il record letto con la frase READ è "-U t1''''' I (I (J r (;
;/ vvv- 2.vvvvvvv-\87.vvvvvvvv
quello prodotto dalla PRINT è il seguente:
- 0.1 OOOOOE + al - 0.920000E + 02
207
Espressioni carattere come identificatori di formato
Se l'identificatore di formato in una frase di I/O è una espressione carattere,il valore dell'espressione o una sua sottostringa deve costituire una specificazionedi formato al momento dell'esecuzione della frase. Se la specificazione di formato
è definita da una sottostringa essa può essere preceduta soltanto da caratteri blank
ma può essere seguita da qualsiasi altro carattere.
Esempio 13.15. Nella frase
READ '(215, 2FIO.0)', N, M, A. B
l'identificatore di formato è costituito dall' espressione carattere'(215, 2F 10.0)';
questa istruzione è allora equivalente alla coppia di istruzioni READ e FORMAT
dell'esempio 13.13.
Esempio 13.16. Siano A e B variabili carattere rispettivamente di lunghezza 2 e
5. Le tre istruzioni:
A = '(2'B = 'FS.3)'PRINT A Il B, XI, X2
hanno, sul record di uscita, lo stesso effetto della frase
PRINT '(2F5.3)', Xl, X2
in quanto il valore dell'espressione A // B è la specificazione di formato (2 F5.3).
Esempio 13.17. Se A e B sono variabili carattere di lunghezza 8, le istruzioni
A = 'vv(313, F'B = '5.3) GGMM'PRINT A II B, LA, LB. Le. XI
hanno, sul record di uscita, lo stesso effetto della frase
PRINT '(313, FS.3)', LA, LB. LC, Xl
Il valore dell'espressione A//B contiene infatti la sottostringa (313, FS.3) che,
essendo preceduta da caratteri blank, è riconosciuta ed utilizzata come specifica
zione di formato.
Esempio 13.18. Sia N una variabile carattere di lunghezza l. Nella frase:
PRINT '('j/N/I'13)',LA. LB, LC
l'identificatore di formato è costituito da un'espressione carattere il cui valore è
208
ottenuto concatenando la costante '(' con il valore di N e con la costante '13)'.Pertanto, se al momento dell'esecuzione della frase PRINT il valore di N è '2',la frase equivale a
PRINT '(213)', LA, LB, LC
mentre, se N vale 'S', essa equivale a:
PRINT '(513)', LA, LB, LC
Da questo esempio si vede che, tramite un identificatore costituito da una espressione carattere, si può associare ad una frase di I/O una specificazione di formatovariabile.
Variabili dimensionate carattere come identificatori di formato
Se l'identificatore di formato in una frase di I/O è il nome di una variabile
dimensionata carattere, allora }an~pecificazione di formato è il risultato della concatenazione dei valori dei singoli elementi nell'ordine in cui essi son~-in~~~-ori~
oppure una sua sottostringa; in questo ultimo caso la specifica~io~e-d;··f~~~t~
può essere preceduta da caratteri blank e seguita da qualunque altro carattere.
Esempio 13.19. Consideriamo le seguenti istruzioni:
CHARACTER * 4 FORM(4)FORM(J) = '(313'FORM(2) = ')'READ FORM, Ix, Iy, Iz
La specificazione di formato associata alla frase READ è (313). Intatti conca
tenando i valori dei quattro elementi di FORM si ottiene una stringa di 16 carat
teri, in cui viene individuata la sottostringa (313) che costituisce appunto unaspecificazione di formato valida.
E' evidente che anche con identificatori di formato costituiti da variabili dimensionate carattere si possono definire specificazioni di formato variabile nelsenso suggerito dall'esempio 13.18.
13.9. Interazione fra lista di ingresso/uscita e specificazione di formato
L'esecuzione di una frase di I/O con formato avviene scandendo insieme,da sinistra verso destra, la lista di I/O e la specificazione di formato. L'acquisi
zione dei dati o la creazione dei records di uscita è contemporanea alla scansionedella lista e della specificazione di formato.
lj In quanto segue occorre tener presente che al momento dell'esecuzione di una
209
r:frase di I/0c:>gni nome di variabile dimensionata presente nella lista viene trattato I.I~
V~pome se fossero specificati tutti gli elementi della variabile nell'ordine in cu~V~
compaiono in memoria.
lnterazione lista-formato nelle operazioni di ingresso
Un'operazione di ingresso inizia con la trasmissione all'interno della memoria
del record che deve essere letto (record corrente). Successivamente inizia la scan
sione della specificazione di formato.• Se, durante la scansione della specificazione di formato, si incontra un descrit
Itore ripetibile che definisce un campo di ampiezza w SI controlla se è già statoI
~.letto ed assegnato un valore a tutti gli elementi della lista. In caso affermativo, I )( 'I i:l'operazione di ingresso ha termine; altrimenti essa prosegue con l'acquisizione , I J \ .
I: ,! !di un dato dal record corrente ossia viene letta una stringa di w caratteri che, in- ( !l/tI ~ " terpretata in base al tipo del descrittore, costituisce il valore da assegnare al primo '..' t\: ,l~id
\ elemento della lista di ingresso il cui contenuto non è stato ancora definito. In: i; IJ ,;
corrispondenza ad un elemento della lista di tipo complesso la scansione della spe- !Ii J
cificazione di formato procede fino ad incontrare un altro descrittore ripetibile Ie, dal record corrente, si leggono due campi.Il procedimento ora descritto può essere realizzato correttamente soltanto se il
dato sul record di ingresso è nella forma prevista dal descrittore e se quest'ultimoè del tipo opportuno in relazione al tipo dell'elemento della lista di ingresso (cfr.
fig. 13.4). Tutte le situazioni che impediscono il corretto svolgimento della operazione provocano l'interruzione dell'intero programma a meno che esse non ven-
Tipo dell'elemento Tipo del descrittorenella lista di I/O ripetibile
intero intero: lw'llw.m / '7~G /' (
reale reale: Fw.d, Dw.d,Ew.d, EW.dEc
doppia precisione Gw.d, GW.dEc
complesso una coppia di descrittori reali
carattere carattere: A, Aw
logico logico: Lw
Figura 13.4. Corrispondenza tra il tipo degli elementi deUa lista di I/O e queUo dei descrittoriripetìbili.
210 211
sia disponibile sull'unità di ingresso il seguente record:
v- 0.2,vO.2v,2l5
READ '(2F5.l, 13)', A, B, N
impone la lettura di due numeri reali da memorizzare in X e Y; i dati devono es
sere scritti su un unico record secondo la specificazione di formato (SFI0.3),
ossia (FIO.3, FIO.3, FlO.3, FIO.3, FI0.3). Ai primi due descrittori ripetibili
F I0.3 vengono associati gli elementi X, Y della lista di ingresso ai quali vengono
quindi assegnati i valori risultanti dall'interpretazione e conversione delle stringhe
presenti nel primo e nel secondo campo rispettivamente. Quando viene incontrato
il terzo descrittore F I0.3 l'operazione termina perché è terminata la scansionedeBi"Usta di ingresso.--------._--- -
A; pertanto la stringa v -0.2 presente nel primo campo di ampiezza S viene inter
pretata come numero reale -0.2, viene convertita nella rappresentazione internafl( - 0.2) e memorizzata in A;
• il secondo descrittore incontrato è ancora un descrittore ripetibile FS.I ; al se
condo elemento della lista di ingresso B, viene assegnato il valore fl(0.2) risultan
te dall'interpretazione e conversione della stringa vO.2 v presente nel secondocampo del record;
• il terzo descrittore incontrato è il descrittore ripetibile 13 e il terzo elemento
della lista è la variabile intera N; la stringa 21S presente nel terzo campo viene allora interpretata come un numero intero che viene assegnato ad N;
• viene incontrata la parentesi finale della specificazione di formato ed essendoormai stato assegnato un valore ad ogni elemento della lista di ingresso, l'operazione ha termine.
Esempio 13.23. L'esecuzione della frase
READ '(F8.\, 2(13, FIO.O))', A. N, B, NM. BM, K, BK
Esempio 13.22. La frase
READ '(5FI0.3)', X, Y
avviene nel modo seguente. Dal primo record vengono letti, secondo la specifi
cazione di formato (F8.I, (13, F 10.0, 13, F 10.0)), cinque valori che vengono
assegnati nell'ordine ad A, N, B, NM, BM. A questo punto si incontra la parentesi
chiusa finale; si inizia allora la lettura di un nuovo record per acquisire i valori da
assegnare a K e BK. Su questo secondo record i dati vengono interpretati secondo
la specificazione di formato che inizia dal punto di riscansione, ovvero essi devonoaccordarsi con la specificazione (13, FIO.O, 13, FIO.O).
(13, (A3, 12, A3, 12), F5.3)
(13, «A3, 15, A3, 15), F5.3, (A3, 15, A3, 15),F5.3))
«A3, 12, A3, 12), (F5.3, 12, F5.3, 12))
(13, A3, A3, 12, 12)
«13, A3, 13, A3), 12)
(13, (A3, 12, A3, 12))
(13, 2A3, 212),(13, 2(A3, 12))
t(2(13, A3), 12)t
(13, 1(A3, 12), F5.3)
(2(A3, 12), rF5.3, 12))
(13, 2(2(A3, 15), F5.3))t
Esempio 13.21. Supponiamo che al momento dell'esecuzione della frase
Esempio 13.20. Nelle seguenti specificazioni di formato la freccia indica il punto
di riscansione; per maggior chiarezza, accanto a ciascuna specificazione viene indi
cata la forma ad essa equivalente.
gano opportunamente trattate come indicato nel cap. 18.• Se, durante la scansione della specificazione di formato, viene incontrato un de
scrittore non ripetibile viene eseguita l'azione da esso descritta e la scansione della
specificazione di formato procede con l'esame del successivo descrittore.
• Quando, durante la scansione della specificazione di formato. si incontra la
parentesi chiusa finale, l'operazione di ingresso termina se la sua esecuzione ha
permesso di definire il contenuto di tutti gli elementi della lista. In caso contrario,'
,I 1\ l'acquisizione dei dati prosegue dal record che, sull'unità di ingresso, segue imrneI diatamente il record corrente; questo nuovo record viene trasferito in memoria
i \ e sostituisce il record corrente. La scansione della specificazione di formato ri-tIl ) .. I,. '
\ ~~e~de a partire dal punto di riscansione che coincide con l'inizio .della specifi, \ ì~ (' . caiìone di formato se questa no~ contiene specificazioni di formato interne; at-
(li I trimenti esso coincide con l'inizio della specificazione di formato che si chiudecon l'ultima parentesi interna destra.
i l'..l'
Esempio 13.24. Sia IND un vettore di IO elementi; \'istruzioneConsiderando che la specificazione di formato (2F5.l, 13) è equivalente a(F5.1, FS.I, 13), l'operazione di lettura avviene nel modo seguente:
• inizia la scansione della specificazione di formato. Il primo descrittore è il descrittore ripetibile FS.I e il primo elemento nella lista di ingresso è la variabile
'Il,READ '(14)', IND il
prevede di leggere un valore per ognuno degli elementi di IND secondo la speci-
II
I
212
ficazione di formato (14); siccome questa specificazione prevede un unico campo
di 4 caratteri, i valori delle lO componenti di IND devono essere scritti ognuno
nelle prime 4 posizioni di un record, per un totale di lO records successivi. I dati
devono invece essere fomiti su un unico record, in lO campi consecutivi di am
piezza 4, se si usa la frase
READ '(1014)', IND
Supponendo infine che i dati vengano acquisiti con l'istruzione
READ '(414)', IND
devono essere predisposti 3 records distinti: il primo deve contenere i valori di
IND(I), IND(2), IND(3), IND(4), il secondo quelli di IND(5), IND(b), IND(7),
IND(8) e infine il terzo quelli di IND(9) e IND(lO). Ogni dato dovrà occupare
un campo di 4 caratteri.
Dagli esempi precedenti risulta evidente che il numero di records letti durante
una operazione di ingresso dipende dal numero di elementi della lista e dalla spe
cificazione di formato; se il numero di records richiesti dall'operazione e maggiore
del numero di records disponibili sull'unità di ingresso, si crea una situazione di
errore che provoca la fine dell'esecuzione dell'intero programma a meno che essa
non sia prevista nei modi descritti nel cap. 18. In ogni caso occorre molta atten
zione nel disporre i dati sui records di ingresso o nello scegliere la specificazione di
formato da associare ad una istruzione di lettura. A questo proposito si osservi
che una specificazione di formato deve essere tale da non imporre la lettura
di records più lunghi di quanto consentito dal supporto fisico su cui essi sono
rappresentati (sui mezzi di ingresso standard la lunghezza massima consentita
è di solito 80 caratteri).
Interazione lista-formato nelle operazioni di uscita
L'esecuzione di una frase di uscita con formato consiste nella creazione in me
moria di uno o più records che successivamente vengono emessi sull'unità di usci
ta. II numero e la struttura dei records creati dipendono dalla lista di uscita, dalla
specificazione di formato e dalla loro interazione. La scansione della lista e del
formato procede nello stesso modo visto per un'operazione di ingresso; in parti
colare ogni volta che nella specificazione di formato si incontra un descrittore ri
petibile, il valore dell'elemento della lista ad esso corrispondente viene convertito
e rappresentato sul record corrente secondo le modalità imposte dal descrittore.
Anche per le istruzioni di uscita deve essere rispettata la corrispondenza di tipo
fra elemento della lista di uscita e descrittore ripe tibile ad esso associato (cfr.
fig. 13.4). Inoltre, e buona regola evitare specificazioni di formato che diano luo-
l
213
go alla creazione di records troppo lunghi, ovvero costituiti da più caratteri di
quanti ne possono essere contenuti su una riga dell'unità di uscita prescelta (le
righe sulle usuali unità di uscita, come stampante, video, terminale, sono di so
lito lunghe 80, 120 o 117 caratteri).
Esempio J3.25. Data la matrice intera MAT dichiarata con la frase
INTEGER MAT (3,2)
e data la variabile carattere N di lunghezza l, a cui si suppone assegnato il valore'3', l'esecuzione della frase
PRINT '('f/N//'I4)', MAT
determina la creazione di due records su ognuno dei quali vengono riprodotti i
contenuti degli elementi di una colonna di MAT secondo la specificazione di for
mato (314). Ricordiamo infatti che la lista di uscita costituita dal nome di matriceMAT è equivalente alla lista:
MAT(I, I), MAT(2, I), MAT(3, I). MAT(I, 2), MAT(2, 2), MAT (3,2)
Così, se MAT contiene la matrice
(- 2)
5 15
-7 -3vengono creati i records seguenti:
vvv l vvv5 vv- 7
vv- 2 vv 15 vv- 3
Esempio J3.26. Supponendo che GG, MM, AA siano variabili intere contenenti
rispettivamente i valori 29, 6,49 l'esecuzione della frase
PRINT 1200, 'GIORNO:', GG, 'MESE:', MM, 'ANNO:', AA1200 FORMAT (3(A7, 13»
dà luogo alla creazione del record seguente:
GIORNO: V'29V' V' MESE: V'v6V' V' ANNO:V'49
Se la frase FORMAT fosse stata:
1200 FORMAT(A7,13)
allora si sarebbero ottenuti tre records di uscita:
GIORNO:v29
vV'MESE: vv6
vvANNO: v49
I
I
II,l'
lili
Il,I,lìI
Figura 13.5. Controllo della spaziatura verticale su stampante.
Esempio 13.27. Il record creato dalla frase PRINT dell'esempio 13.26 verrebbe
riprodotto su una riga della stampante privato del primo carattere. ossiaI
214
Osserviamo che per ottenere tre records distinti con la frase PRINT*, ossia senzaspecificazione di formato esplicita, si dovrebbero eseguire tre operazioni di uscita
distinte:
PRINT *, 'GIORNO:', GGPRINT -. 'MESE:', MMPRINT *, 'ANNO:', AA
Specificazioni di formato vuote
In F77 sono permesse istruzioni di I/O con specificazioni di formato vuote.
Se la specificazione di formato è vuota anche la lista deve esserlo. Sono quindi
ammesse le istruzioni seguenti:
REA D '()'
PRINT '( )'
L'effetto della prima frase è quello di ignorare il record corrente qualunque sia
il suo contenuto; quello della seconda è di creare un record vuoto.
Primo carattere
blank
o
+
Effetto
spaziatura singolo: il record vieneriprodotto sulla riga successivaall'ultima già stampata
spaziatura doppia: il record vieneriprodotto a distanza di una rigadall'ultima già stampata
solto di pagina: il record èriprodotto sulla prima rigadella pagina successiva
sovrastampa: il record èriprodotto sulla stessa rigadel precedente
215
I
II
,.
II
13.10. Controllo della spaziatura verticale su stampante
I records creati durante l'esecuzione di una frase di uscita possono essere
emessi sull'unità di uscita uno alla volta oppure tutti insieme, al termine dell'ope
razione. Le modalità che regolano la gestione dei records di uscita dipendono dal
sistema e dalle unità usate e può essere anche prevista un'emissione «globale»
dei records di uscita nel senso che soltanto alla fine dell'esecuzione di un program
ma vengono riprodotti sull'unità di uscita tutti i records creati da tutte le frasi
di uscita presenti nel programma stesso. In ogni caso ogni record viene riprodotto
a partire dal margine sinistro di una nuova linea sull'unità di uscita prescelta.
In generale, ogni sistema di calcolo prevede almeno una unità di uscita, che
chiameremo stampante, sulla quale è possibile controllare la spaziatura verticale
tra due linee di. uscita successive mediante opportune indicazioni nella specificazione di formato. Infatti, quando il record viene emesso su stampante.. il suo
primo carattere non viene stampato ma viene usato per determinare la p~izlone'llldella riga su cui il record verrà stampato rispetto all'ultima riga già stampata ql: Ilrispetto all'inizio del foglio di stampa. Nella fig. 13.5 viene indicato l'effett~·che' ,
si ottiene quando il primo carattere è blank, O(zero), I, +; qualunque altro carat
tere che si trovi nella posizione iniziale del record di uscita viene di solito conside
rato come un carattere blank anche se in F77 non è stabilita alcuna norma al
riguardo.
IORNO:v29 vvMESE:vv6 vv ANNO:v49
Per evitare la perdita del primo carattere potremmo usare. ad esempio. la specificazione di formato:
(A8, 13, 2(A7, 13»
Avendo aumentato di un carattere l'ampiezza del primo campo, la stringa
GIORNO: viene riprodotta nelle 7 posizioni più a destra del campo ed il primo
carattere del campo. che è anche il primo del record. è un hlank.
Il primo carattere del record di uscita su stampante può essere specificato
anche usando opportuni descrittori non ripetibili. come verrà specificato nelparagrafo successivo.
13.11. I principali descrittori non ripetibili
Il descrittore nX
Questo descrittore. in cui n è una costante intera positiva senza segno che non
può essere omessa neppure se uguale ad I, consente di spostarsi di n caratteri sul
record corrente. L'utilizzazione del descrittore nX permette quindi di ignorare
n caratteri su un record in ingresso o di creare un campo di n caratteri blank su
fii
I111
216
un record di uscita. Di solito questo descrittore viene usato nelle specificazioni
di formato associate a Istruzioni di uscita per spaziare opportunamente I risultatioppure per creare un blank come primo carattere del record. Ad esempio la specificazione di formato
(IX, 3(A 7,13»
consente di non perdere il primo carattere nella stampa del record dell'esempio!13.26, ed ha quindi lo stesso effetto della specificazione indicata nell'esempio r13.27.
Esempio 13.28. L'esecuzione della frase
PRINT '(5X, 14, 5X, EI3.6)', N, X, M, Y
avviene nel modo seguente:
• il primo descrittore incontrato nella scansione di formato è 5X; allora sul record di uscita vengono riempite con caratteri blank le prime 5 posizioni;
• il secondo descrittore è il descrittore ripetibile 14; ad esso viene associato il
primo elemento della lista di uscita, N, il cui valore viene riprodotto sul record
allineato a destra nel campo che va dalla sesta alla nona posizione;
• il terzo descrittore è ancora 5X; esso provoca l'inserimento di caratteri blanknelle posizioni dalla decima alla quattordicesima;
• il quarto descrittore, E13.6, è ripetibile e viene associato al secondo elementodella lista, X, il cui valore viene opportunamente riprodotto sul record su un cam
po di ampiezza 13 a partire dalla quindicesima posizione;
• si incontra infine la parentesi finale e, siccome i valori di M e di Y devono essereancora riprodotti, la scansione della specificazione di formato riprende dall'inizio;
viene così creato un secondo record che ha la stessa struttura del primo, sul quale
sono rappresentati i valori di M ed Y.
I descrittori 'hl" . ho' e nHh l · · . ho
Durante un'operazione di uscita è possibile inserire sul record corrente una
stringa hl ... hn costituita da caratteri codificabili dal sistema mediante uno deidescri ttori:
'hl' .. hn ' ; nHh l··· hn
Il primo descrittore, non permesso in F66, ha la forma di una costante carattereed il secondo, disponibile anche in F66, è stato mantenuto per consentire che pro
grammi scritti in F66 potessero essere eseguiti su elaboratori che realizzano il nuovo standard.
217
Esempio 13.29. Le istruzioni
PRINT 1000, RAGGIO, AREA1000 FORMAT (lX, 'RAGGIOv='. E13.6, 3X, 'AREAv=', E13.6)
permettono di visualizzare i valori delle variabili RAGGIO e AREA preceduti,
rispettivamente, dalle stringhe RAGGIO v = e AREA v =; se RAGGIO vale 2.
e AREA vale 12.5664, viene creato il record
vRAGGIOv= + 0.200000E + 01 vvv AREAv= + 0.125664E + 02
Si osservi che il carattere blank che precede la stringa RAGGIO v = e i tre blanks
che precedono la stringa AREA v = vengono creati sul record per effetto dei de
scrittori IX e 3X rispettivamente.Lo stesso record può essere ottenuto con una delle seguenti coppie di istru
zioni:
PRINT 1000, RAGGIO, AREA1000 FORMAT (lX. 8HRAGGIOv=, E13.6, 3X, 6HAREAV=, E13.6)
PRINT 1000, 'RAGGIOv=', RAGGIO, 'AREAV=', AREA1000 FORMAT (lX, A8, E13.6. 3X, A6, E13.6)
PRINT 1000, 'vRAGGIOv=', RAGGIO,'vvvAREAV=', AREA1000 FORMAT (2(A, EI3.6))
e con diverse altre combinazioni di specificazioni di formato e liste di uscita.
Esempio 13.30. Con le istruzioni
PRINT 20002000 FORMAT (vvPROBLEMAvTESTV')
si crea un record contenente la stringa di caratteri vvPROBLEMA vTEST v. Si
noti che la specificazione di formato non contiene descrittori ripetibili e che la
lista di uscita è vuota.
Se la stringa di caratteri che si vuole inserire in un record di uscita contiene un
apice, questo deve essere scritto come una coppia di apici consecutivi nel descrittore 'hl ... h
nI o come un solo apice nel descrittore nlfh, ... hn · Se poi
la specificazione di formato viene associata alla frase di uscita tramite un identificatore costituito da una costante carattere, allora tutti gli apici devono esse
re sostituiti da una coppia di apici consecutivi.
Esempio 13.31. Il messaggio 2vNONvE'v3 può essere stampato con varie com
binazioni di frasi di uscita e specificazioni di formato, fra le quali:
218
PRlNT 2000. 2. 32000 FORMAT(lX, Il, IX, 'NONvE"v', Il)
PRINT '(IX, Il, IX, "NONvE""v", Il)', 2, 3
PRINT 2000, 2,32000 FORMAT (IX, Il, IX, 7HNONvE'v, Il)
PRlNT'(AlI )', '2vNONvE"v3'
PRINT '(A)', 'v2vNONvE"v3'
PRlNT'(IX, Il, A, Il)', 2, 'vNONvE"v',3
I descrittori 'hl ... h~ e nHh l· .. hn possono essere usati per ottenere comeprimo carattere di un record uno di quelli previsti in fig. 13.5. Così, ad esempio,il primo carattere del record creato con la frase
PRINT 555555 FORMAT (l', I5X, 'INIZI0vDELvFOGLIO')
è: l. Se il record viene emesso su stampante, esso viene riprodotto sulla prima rigadel foglio di stampa successivo, privato del primo carattere.
Il descrittore / (sbarra)
Una specificazione di formato può descrivere la struttura di più records siaquando viene riscandita più volte a causa della lunghezza della lista di I/O, siaquando contiene il descrittore non ripetibile [, Questo descrittore infatti indica
la fine della trasmissione di informazioni da (su) un record e l'inizio della tra
smissione dal (sul) record successivo. In ingresso ciò significa che gli eventuali
caratteri non ancora letti sul record corrente vengono ignorati e, se la lista di in
gresso prevede la lettura di altri dati, questi devono essere fomiti sul record suc
cessivo. In uscita la sbarra fa sì che il record corrente venga considerato concluso
e che venga dato inizio alla creazione di un nuovo record. Osserviamo che in una
specificazione di formato si può omettere la virgola che precede un descrittoresbarra e quella che lo segue.
Esempio 13.32. L'istruzione
READ '(2FIO.3/214)', X, Y, I, J
indica che devono essere letti due numeri reali e due interi. La specificazione di
formato è tale per cui i dati devono essere fomiti su due records: il primo deve
contenere i valori reali da memorizzare in X e Y scritti secondo la specificazione
di formato (2FIO.3); il secondo deve corrispondere alla specificazione (214) edeve contenere i valon da assegnare a I e J. In altri termini, i dati devono esserefomiti come se fossero utilizzate le due istruzioni di lettura seguenti
READ '(2FIO.3)', X, YREAD '(214)', I, J
219
Esempio 13.33. Se VOTI è un vettore intero, l'esecuzione della frase
PRINT '(IX, "VETTORE vDEI v VOTI "/5(l X, 16»', VOTI
causa la creazione di un record che contiene il messaggio VETTOREvDElvVOTI
e di uno o più records successivi su ognuno dei quali sono rappresentati i valoridi cinque elementi di VOTI su campi di ampiezza 6 separati da un carattereblank. Il numero di records successivi al primo dipende dalla lunghezza di VOTI.Così ad esempio, se VOTI ha lunghezza 5 l'effetto della frase è quello di creareun solo record successivo al primo contenente i valori dei cinque elementi di
VOTI; se invece VOTI ha lunghezza 12 la frase provoca la creazione di tre recordssuccessivi al primo l'ultimo dei quali contiene due soli dati. Supponendo di voler
creare, dopo il primo, un record per ogni elemento di VOTI, si può usare la frase
PRINT '(IX, "VETTOREvDElvVOTI"/(lX, 16»', VOTI
nella cui specificazrone dI formato la coppia di parentesi interne serve ad impedire
la riproduzione della stringa VETTORE vDEI vVOTI su tutti i record successivial primo.
E' possibile distanziare tra loro le righe di stampa prodotte da una istruzione
di uscita inserendo nella relativa specificazione di formato più sbarre consecu
tive. Infatti se durante la scansione della specificazione di formato si incontra
una sbarra l'operazione di uscita deve continuare sul record successivo. La scan
sione del formato procede quindi con l'esame del successivo descrittore; se questo
è ancora una sbarra, il record corrente viene lasciato vuoto e l'operazione di uscitacontinua sul record successivo. Questo processo si ripete finché non si incontraun descrittore diverso dalla sbarra oppure la parentesi finale della specificazionedi formato. Ogni record lasciato vuoto viene riprodotto sul mezzo di uscita comeuna riga bianca. Così, eseguendo la frase
PRINT '(IX, 214///2(1 X, EI3.6»', N, M, A, B
si creano quattro records di cui il seconao ed 11 terzo VUOtI.
I3.12.La lista di ingresso/uscita
Una lista di I/O può contenerenomìdivarìabìle, nonudìelementì di variabile
dimensionata, nomi di variabile dimensionata e nomi di sottostringhe. Inoltre una
lista di uscita può contenere espressioni, eventualmente costituite da singole co
stanti. Di una lista di l/O possono far parte elementi più complessi, detti liste conDO-implicito, che rappresentano in forma sintetica tutta la lista o parte di essa, e
che sono usate soprattutto in connessione con l'ingresso/uscita di variabili dimensionate.
220 221
PRINT *, (V(I), I = M, N)
oppure con la sequenza di istruzioni
DO 100, 1= M. NPRINT -. V(I)
100 CONTINUE
Si osservi che gli stessi valori vengono stampati nel primo caso con l'esecuzione
di una sola operazione e nel secondo caso con quella di N - M + 1 operazioni.
Volendo stampare i valori degli stessi elementi di V a gruppi di 3 su linee
successive, si può usare la frase:
PRINT '(3(1 X, E13.6»)', rvrn. l = M. N)
Esempio 13.36. Dato il vettore V specificato dalla frase
REAL V( - 20 : 20)
si vogliono visualizzare sull'unità di uscita standard i valori di V(M), V(M + 1),
..., V(N) dove M ed N sono noti e tali che - 20 ~ M ~ N ~ 20. Tale scopo può
essere ottenuto con l'istruzione
Lista con DO-implicito
Una lista con DO-implicito ha la forma seguente:
(5f' ,v = el
, e2
, e3
)dove:
• 5f' che diremo lista del DO-implicito. è una lista di ingresso o una lista diuscita coerentemente con il tipo di lista di cui la lista con DO-implicito fa parte;5f' può contenere a sua volta una o più liste con DO-implicito;
• v, el , e2, e3 hanno lo stesso significato dei simboli v, el, e
2, e
3visti nell'istru
zione DO (cfr. cap. l O): v è detta variabile della lista con DO-implicito.
Al momento dell'esecuzione di una istruzione di I/O nella quale compareuna lista con D0-implicito, viene calcolato il contatore C in base ai valori delle
espressioni el , e2, e3 esattamente come se dovesse essere eseguita un'istruzione
del tipo DO n v = el' e2 , er La lista con DO-implicito è equivalente a quella otte
nuta riscrivendo C volte consecutive la lista 5f'; ad ogni ripetizione di 5f' il valore
di v viene modificato come nella realizzazione di un ciclo-DO e di conseguenza
vengono modificati i nomi dipendenti da v che compaiono in .!f. Si può direquindi che 5f' costituisce il rango del DO-implicito.
Esempio 13.34. Le liste con DO-implicito seguenti equivalgono alle liste esplicitescritte accanto
(V(I), I = 1,4)
(A(I, J), J = 1, 3)
(X, Y, K = 1,5)
(N, ~ * N, N = 8,2, - 2)(U(I + 1), V(I - 1), I = 3, 1, - 1)
(K, W(K), K = 1,7,2)
V(l), V(2), V(3), V(4)
A(I, 1), A(I, 2), A(I, 3)
X,Y,X,Y,X,Y,X,Y,X,Y8, 2 * 8,6, 2 * 6,4, 2 * 4, 2, 2 * 2U(4), V(2), U(3), V(l), U(2), V(O)
1, W(l), 3, W(3), 5, W(5), 7, W(7)
Se la lista !f di un DO-implicito contiene a sua volta una lista con DO-implicito,
si ha una situazione di annidamento per la quale valgono le regole viste nel cap.
lO; in particolare le variabili di più viste con DO-implicito annidate devono essere
distinte.
Esempio 13.37. Data una matrice, MAT, l'istruzione
READ *, «MAT(I, J), I = l, N), J = l, M)
Esempio 13.35. Data la matrice reale AMAT dichiarata da
REAL AMAT (l4, 14)la sequenza di istruzioni
DO 100 I = l, 14PRINT '(5(5X, EI3.6»', (AMAT(I, J), J = l, 14)
100 CONTINUE
prevede la scrittura sull'unità di uscita standard di tutti gli elementi di AMAT.
Infatti per ogni valore che I assume durante l'esecuzione del ciclo-DO esplicito,la lista della frase PRINT è costituita dagli elementi AMAT (I, l), AMAT (I, 2),
..., AMAT (I, 14), ossia dagli elementi della l-esima riga di AMAT. Ciascuna riga
di AMAT viene quindi riprodotta su tre records contenenti rispettivamente i valori
degli elementi dal primo al quinto, dal sesto al decimo, e dall'undicesimo al quattordicesimo.
consente di acquisire N * M valori da attribuire agli elementi MAT(I, J) con
l ~ I ~ N e l ~ J ~ M. Gli stessi valori, nello stesso ordine, possono essere letti
con la sequenza di istruzioni
DO 100 J = l,MDO 100 1 = l, NREAD *, MAT(I, 1)
100 CONTINUE
in cui si effettuano N * M operazioni di lettura anziché una sola. In entrambi i
casi gli elementi MAT (I, J) vengono letti per colonne in quanto, per ogni valore
dell'indice di colonna J, viene fatto variare l'indice di riga l. Volendo stampare per
righe questi valori si può usare la frase
PRINT *, «MAT(I, J), J = l, M), I = l, N)
oppure la sequenza di istruzioni
l
222
DO 200 1= 1, NDO 200 J = l,MPRINT -, MAT(I, J)
200 CONTINUE
In quest'ultimo caso si ha la stampa di N * M linee ciascuna contenente un solo
valore.
13.13. Le frasi READ (u, f) e WRITE (u, f)
Le frasi READ e PRINT considerate fino ad ora consentono di effettuare le
operazioni di I/O esclusivamente sulle unità standard. Così, per esempio, se il
sistema utilizza come unità standard di ingresso e di uscita il terminale video, non
è possibile usare queste frasi per leggere dati da un lettore di schede o riprodurre
i risultati sul foglio di carta di una stampante.
Per usare mezzi di I/O diversi da quelli standard, è necessario ricorrere ad istru
zioni di I/O nelle quali sia esplicitamente indicato quale mezzo di I/O deve essere
utilizzato.
A questo proposito si osservi che l'insieme dei records letti o scritti con una
istruzione di I/O del tipo visto fino ad ora costituisce un file esterno sequenzialela cui trasmissione avviene attraverso le unità di I/O standard. Infatti, come sarà
ulteriormente specificato nel cap. 18, un insieme di records costituiti da caratteri
interpretabili in base ad opportune specificazioni di formato è un file. Un file è
detto sequenziale se per accedere ad un suo record si deve scorrerlo tutto a par
tire dal primo record, e viene detto esterno se contiene informazioni destinate ad
essere trasmesse mediante una qualunque unità di I/O.
Per individuare un qualunque file esterno si usa un numero intero non negativo
detto numero di unità, che consente anche di individuare il mezzo (unità) di I/O
che permette la trasmissione delle informazioni contenute nel file. In alcuni casi
la corrispondenza tra un file esterno, un numero di unità e un mezzo di I/O può
essere prestabilita dal sistema e in altri casi è possibile stabilirla mediante oppor
tuni comandi dati al programma Iinker; in ogni caso tale corrispondenza può
essere stabilita nel programma tramite l'istruzione OPEN (cfr. cap. 18). E' possi
bile specificare il file, e quindi l'unità di I/O interessati da un'operazione di I/O
usando come frase di ingresso la seguente:
READ (u, f) lista-di-ingresso
e, come frase di uscita, la seguente:
WRITE (u, f) lista-di-uscita
dove:
223
- READ e WRITE sono le parole che identificano le frasi;
• u è un'espressione intera il cui valore, al momento dell'esecuzione della frase,
rappresenta il numero di unità del file oggetto dell'operazione. Se l'operazioneavviene tramite l'unità standard u può essere un asterisco _;
• f è un identificatore di formato.
Esempio 13.38. Diamo alcuni esempi di istruzioni di ingresso sintatticamente corrette:
READ (5, '(1013)') MI, M2, M3
READ (IR, '(1013)') MI, M2, M3
READ(K + l, '(1013)') MI,M2,M3
READ(-, '(1013)') MI,M2,M3
READ (7,100), MI, M2, M3
100 FORMAT (1013)
L'esecuzione delle frasi READ (u, f) e WRITE (u, f) avviene allo stesso modo
di quella delle frasi READ f e PRINT f (cfr. § 13.9). Pertanto le istruzioni:
READ (-, f) lista-di-ingresso
WRITE (*, f) lista-di-uscita
sono equivalenti, nell'ordine, a:
READ f, Iista-di-ingresso
PRINT f, Iista-di-uscita
e le frasi:
READ r-, -) lista-di-ingresso
WRITE (-, -) lista-di -uscita
equivalgono alle frasi guidate dalla lista:
READ -, lista-di-ingresso
PRINT -, lista-di-uscita
13.14. Esempi di stampa di variabili dimensionate
Nel calcolo scientifico si presenta spesso la necessità di manipolare variabili
dimensionate di tipo numerico, a una o due dimensioni, e quindi di leggere e
stampare, tutti o in parte, i contenuti dei loro elementi. In generale la lettura
degli elementi di una variabile dimensionata non presenta particolari difficoltà,
224
una volta stabilito l'ordine in cui si vogliono far leggere i dati. La stampa invece
può presentare alcune difficoltà, soprattutto se si vuole che l'insieme dei dati
stampati sia facilmente leggibile ed interpretabile. E' evidente che l'istruzionedi uscita guidata dalla lista è in questo caso poco opportuna e che conviene invece
usare istruzioni di uscita che facciano riferimento ad una specificazione di forma
to. Negli esempi che seguono si vuole mettere in luce quali siano le considerazioni
che generalmente possono essere fatte per stabilire una specificazione di formato
opportuna in base alla lista degli elementi che si devono stampare. In tutti gli
esempi supponiamo che la stampante sia identificata dal numero di unità 2 e che
le linee di stampa siano lunghe 80 caratteri.
Esempio 13.39. Vogliamo stampare i valori degli elementi di una matrice di tipo
intero il cui dichiaratore è MAT (0:7,20:27). Si vuole che tali valori siano stam
pati per righe, una riga su ogni linea di stampa, e che siano preceduti dall'intesta
zione
STAMPA DI MAT PER RIGHE
Scegliendo il descrittore Il O per la stampa di ciascun elemento, e considerando
che ciascuna riga di MAT è composta da 8 elementi, è possibile descrivere la
struttura di una linea di stampa corrispondente ad una riga di MAT con la specifi
cazione di formato (81 lO) come mostrato nella figura seguente.
INTEGER MAT(0:7,20:27)
DOlO 1=0,700 IO J = 20,27MAT(I,J)=I.J
lO CONTINUEWRlTE (2, '(30X, "STAMPAvDlvMATvPERvRlGHE" 130X, 23 (" - ") Il
• (8110)') «MAT (I, J), J = 20,27), I = 0,7)
END
STAMPA DI MAT PER RIGHE
225
Esempio 13.40. Sia REL una matrice reale con M righe e N colonne, con N > S.
Si vogliono stampare gli elementi di REL per righe.Se si sceglie il descrittore E 13.6 per stampare ogni elemento e si decide di se
parare ogni valore dal successivo con due caratteri blank, abbiamo un totale di15 caratteri occupati dalla rappresentazione del valore di ciascun elemento.
Pertanto, essendo ciascuna linea composta da 80 caratteri, potremo al più stam
pare 5 valori per linea, e siccome si è supposto N > 5 saranno necessarie più linee
di stampa per riprodurre ciascuna riga di REL. Consideriamo i due casi seguenti:
a) N è un multiplo di 5; in tal caso ciascuna riga di REL può essere riprodotta
esattamente su N/S linee successive;b) N non è un multiplo di 5; in tal caso ciascuna riga di REL può essere ripro
dotta su più linee, di cui l'ultima contenente meno di 5 valori.Nel caso a) la stampa di REL può essere effettuata con un'unica operazione;
in fig. 13.7 si tratteggia un programma relativo alla stampa di una matrice RELdi 3 righe e IO colonne e si riportano le linee di stampa ottenute. Nel caso b)
è conveniente eseguire tante operazioni di stampa quante sono le righe di REL;
in fig. 13.8 si riporta un esempio relativo ad una matrice REL di 3 righe e 12
colonne.
C STAMPA DI REL (M, N) CON N MULTIPLO DI 5PARAMETER (M = 3, N == lO)REAL REL (M, N)
DO lO I=I,MDO lO J=I,N
IO REL(l,J)=ld+0.005
WRITE (2, ISO) N/5, «REL(l, J), J = I, N ),1 = I, M )ISO FORMAT(l4X,'STAMPAVDIVRELVPERvRIGHE',12,
• 'LlNEEvPERvCIASCUNAvRIGA' Il 5 (2X, E13.6»)
END
STAMPA DI REL PER RIGHE, 2 LINEE PER CIASCUNA RIGA
Figura 13.7. Programma e stampa relativi al caso a) deU'esempio 13.40.
o o o o o o o20 21 22 23 24 25 2640 42 44 46 48 50 5260 63 66 69 72 75 7880 84 88 92 96 100 104
100 105 110 115 120 125 130120 126 132 138 144 150 156140 147 154 161 168 175 182
Figura 13.6. Programma e stampa relativi all'esempio 13.39.
o275481
108135162189
0.100500E+Ol0.600500E+010.200500E+Ol0.120050E+020.300500E+Ol0.180050E+02
0.200500E+010.700500E+Ol0.400500E+010.140050E+020.600500E+010.210050E+02
0.300500E+010.800500E+01O.G00500E+01O.lG0050E+02O.900S00E+01O.2400S0E+D2
D.4DDSDDE+D10.9DDSDDE+DlD.8DDSDDE+DlD.18DDSDE+D2D.12DDSDE+D2D.270DSOE+D2
D.SDDSDDE+D10.lDDDSDE+D2D.IDDDSDE+D2D.2DDDSDE+D2D.lSDDSDE+D2D.30DDSDE+D2
Il 226 227
Figura 13.8. Programma e stampa relativi al caso b) dell'esempio 13.40.
'('fICAR (Nl : Nl) Il '110)'
RIGA 10.100500E+01 0.200500E+01 0.300500E+01 0.400500E+01 0.500500E+010.600500E+01 0.700500E+01 0.800500E+01 0.900500E+01 0.100050E+020.110050E+02 0.120050E+02
RIGA 20.200500E+01 0.400500E+01 0.600500E+01 0.800500E+01 0.100050E+020.120050E+02 0.140050E+02 0.160050E+02 0.180050E+02 0.200050E+020.220050E+02 0.240050E+02
RIGA 30.300500E+01 0.600500E+01 0.900500E+01 0.120050E+02 0.150050E+020.180050E+02 0.210050E+02 0.240050E+02 0.270050E+02 0.300050E+020.330050E+02 0.360050E+02
D020 I = l,MIDO 20 J = I,NIINT (I, J) = I • J
20 CONTfNùE
WRITE (2, '('tICAR (NI : Nl)11 '110)') «INT(I, n. J = l. Nn.1 = I. MI)
END
Fipra 13.9. Propanma relativo ...·aempio 13.41.
C ESEMPIO DI UTILIZZO DI SPECIFICAZIONI DIC FORMATO VARIABILE
INTEGER INT (50,50)CHARACTER • 8 CARCAR = '12345678'
C LETTURA DI MI <; 50 E NI.;;; 80 'DREAD., MI, NlWRITE (2, 150) MI, NI
150 FORMAT(lOX, 'STAMPAvDELLAvSOTTOMATRICE (',12,','·12, ')VDIVINT, VPERvRIGHE')
STAMPA DELLA SOTTOMATRICE 5, 4) DI INT, PER RIGHE
1 2 3 42 4 6 83 6 9 124 8 12 165 lO 15 20
STAMPA DELLA SOTTOMATRICE 5. 6) DI INT, PER RIGHE
2 3 4 5 64 6 8 lO 126 9 12 15 188 12 16 20 24
lO 15 20 25 30
STAMPA DELLA SOTTOMATRICE 5. 8) DI INT. PER RIGHE
1 2 3 4 5 6 7 82 4 6 8 lO 12 14 163 6 9 12 15 18 21 244 8 12 16 20 24 28 325 lO 15 20 25 30 35 40
Figura 13.10. Esempi di stampe relative aD'esempio 13.41.
DO IO I=I,MDO IO J=I,NREL (I, J) = I • J + 0.005
STAMPA DI REL(M, N), CON N MAGGIORE DI 5E NON MULTIPLO DI 5PARAMETER (M = 3, N = 12)REAL REL (M, N)
END
WRITE (2,200) N/5 + IFORMAT(l4X, 'STAMPAVDIVRELVPERvRIGHE, ',12,
• 'LINEE vPERvCIASCUNA v RIGA'I/)DO 20. I = I. M
WRITE (2,150) I, (REL (I, J), J = I, N)CONTINUEFORMAT (IX, 'RIGA', I1/5(2X, EI3.6»
STAMPA DI REL PER RIGHE, 3 LINEE PER CIASCUNA RIGA
cc
Esempio 13.41. Data la matrice intera INT di SO righe e SO colonne, si voglionostampare per righe gli elementi INT (I, J), con l ~ I ~ M1 e 1~ J ~ N 1, dove
M1 e N1 sono assegnati. Se si sceglie il descrittore 110 per ogni elemento, si pos
sono stampare al più 8 elementi per linea. Il programma tratteggiato in fig. 13.9
dimostra come si possono usare specificazioni di formato variabile (cfr. esempio13.18) per stampare su ogni linea esattamente N1 valori, se N1 è minore o ugualedi 8.
Nel programma ci serviamo dell'identificatore di formato costituito dall'espressione carattere
IO
200
":!t
I20
150
I
l
228229
dove CAR (N l : N l) è la sottostringa costituita dal carattere che in CAR occupa
la posizione Nl. Essendo CAR uguale a '12345678', il valore di CAR (NI : Nl)
è proprio il «numero intero» Nl. Così, se Nl vale 4, CAR (NI : Nl ) è uguale a
'4' e la specificazione di formato è equivalente a (4J l O), mentre se N l vale 8, essaequivale a (8110).
In fig. 13.10 si riportano le stampe ottenute con il programma di fig. 13.9per MI = 5 e N I = 4. 6 e 8 rispettivamente.
13.15. Altri descrittori
Il descrittore Iw.m
II descrittore ripetibile IW.m individua un campo destinato alla rappresenta-
li
lzione d. i un numero intero, ~ in i!1~~esso equivale a Iw. !~ .!:!~iJil !.·I dato viene )
. rappresenjatn nel campo di ampiezza w con almeno m cifre, di cui 1~ prime Yl:uali lia zero se il numero è composto da meno di m cifre. Così, ad esempio, se I, J, K I)'..... "'---'---~~'---'----'- .. J
\ valgono rispettivamente 3, 22 e 546, la frase--
Esempio 13.42. La rappresentazione del numero - 2 x 1015 che si ottiene con f'il descrittore EI1.3E3 è - 0.200E + 015, mentre lo stesso numero viene rap- ,
presentato come - 0.200E + 0015 se si usa il descrittore EI2.3E4.
I descrittori GW.d e GW.dEc
I descrittori ripetibili GW.d e GW.dEc sono descrittori reali e sono quindiequivalenti In Ingresso a tutti gli altri descrittori reali. In uscita essi si comportano
in modo diverso a seconda dell'ordine di grandezza del numero x che deve
essere rappresentato nel campo di ampiezza w.
Se Ix I< 0.1 oppure Ix I~ IOd, i descrittori Gw.d e Gw.dEc equivalgono a
Ew.d ed Ew.dEc rispettivamente.
Se l Oi-I ~ Ix I< l o', con O~ i ~ d, allora si ~ttiene u~a - rapprese~~Zi~~ iesterna uguale a quella prodotta da un descnttore Fw.d, con d - dIA
e 'ii = w - k, seguita da k caratteri blank, dove k = 4 per il descrittore Gw.d J\mentre k = c + 2 per il descrittore GW.dEc.
PRINT '(314.2)', I, J, K
produce il recordEsempio 13.43. Nella seguente tavola si riportano le rappresentazioni esterne
di alcuni numeri reali ottenute in corrispondenza di diversi descrittori F, E, G.
vv03 vv 22 v546.
w ~ d + c + 5.
E ± O... Obl·· . br
con (c - r) cifre zero prima di bl" Se Ib I~ IOc , il descrittore EW.dEc non può
essere usato e il campo viene riempito di asterischi. In ogni caso la rappresentazione (13.2) implica che deve essere
dove al'" ad ed exp hanno lo stesso significato loro attribuito nella rappresentazione (13.1). Se la caratteristica b del dato in uscita è esprimibile, in
base dieci, come ± bi'" br ed è r ~ c (ossia Ib I< IOr , r ~ c), allora in (13.2)exp ha la forma seguente
RappresentazioneF12.5 E12.5 G12.5 G12.5E3
interna
f1 (243762.0) 243762.00000 vO.24376E + 06 vO.24376E+ 06 0.24376E + 006
f1 (-243762.0) ************ -0.24376E + 06 -0.24376E + 06 -.24376E + 006
f1 (-24376.2) -24376.20000 -0.24376E + 05 v-24376.vvvv -24376.vvvvv
f1 (-23.54) vvv-23.54000 -0.23540E + 02 v -23.540vvvv -23.540vvvvv
f1 (0.32693) vvvvvO.32693 v0.32693E + 00 vO.32693vvvv 0.32693vvvvv
f1 (0.021582) vvvvvO.02158 vO.21582E-01 vO.21582E-01 0.21582E -001
f1 (0.00021582) vvvvvo.ooozz vO.21582E-03 vO.21582E- 03 0.21582E - 003
± O.al ... ad exp( 13.2)
Il descrittore Ew.dEc
II descrittore ripetibile t:.w.dEc individua su un record di I/O un campo desti
nato alla rappresentazione di un numero reale.!,!! ingresso, esso equivale a tutti
gli altri descrittori reali, mentre in uscita esso produceunà" rappresentazionedeldato, nel~~~'podiampiezza w, della forma
Quando, nella scansione di una specificazione di formato, si incontra il descrittore l'operazione di I/O ha termine se è stato trasmesso il valore di tutti
gli elementi della lista. Questo descrittore, che può non essere seguito e preceduto
da virgole, è utile essenzialmente per evitare che messaggi «non desiderati» venga
no riprodotti sui records di uscita.
230
Il descrittore Lw
Il descrittore ripetibile Lw individua un campo di ampiezza w destinato alla
rappresentazione di un valore logico. In ingresso, il valore «vero» deve essere in
una delle forme T, . T , .TR VE. ed il valore «falso» in una delle forme F..F.
.F ALSE.; questi caratteri possono essere seguiti da qualunque altro caratt.ere -nei
campo di ampiezza w loro riservato. In uscita i valori «vero» e «falso» sono rap
presentati rispettivamente dai caratteri T e F preceduti da w - l caratteri blank.
Il descrittore (due punti)
231
Ii
;1
I
~i[
I,
, I
i:
J descrittori Tn, TRn, TLn
l descrittori Tn, TRn, TLn sono chiamati descrittori di fabulazione in
quanto permettono di specificare, mediante la costante intera positiva senza
segno n che in essi compare, la posizione sul record corrente del successivo dato
da trasmettere. In particolare, il descrittore Tn indica che il campo relativo al
prossimo dato inizia con l'n-esimo carattere del record. Per spiegare invece
l'effetto dei descrittori TRn e TLn indichiamo con p la posizione sul record
corrente del carattere finale dell'ultimo campo utilizzato; il descrittore TRn
(TLn) indica allora che il campo destinato al prossimo dato inizia dalla posi
zione p + l + n (p + l - n). In altre parole TRn e TLn specificano di quante
posizioni deve essere spostato, a destra e a sinistra rispettivamente, l'inizio del
campo successivo rispetto alla posizione (p + I)-esima. Il descrittore TRn è quin
di equivalente ad nX mentre TLn è equivalente a TI se (p + l - n) ~ l.
Esempio 13.44. Se I è una variabile intera e CHAR una variabile carattere di lun
ghezza 7, la frase
READ '(T5, 14, TL4, A7)', I, CHAR
viene così eseguita. Il descrittore T5 causa un salto al quinto carattere del re
cord corrente; il descrittore 14 viene poi associato alla variabile I il cui valore
viene letto nel campo che va dal quinto all'ottavo carattere del record. Il descrit
tore TL4 indica che il campo relativo al dato successivo inizia a partire dalla
Quinta posizione del record corrente in quanto si ha p = 8 e n = 4. Il descrittore
A7 viene poi associato alla variabile CHAR il cui valore viene letto nel campo che
va dal quinto all'undicesimo carattere del record. In questo modo i caratteri pre
senti sul record nelle posizioni 5, 6, 7, 8 vengono letti due volte e vengono inter
pretati nei due casi in modi completamente diversi. Se ad esempio il record lettoè composto dalla successione di caratteri
12341986/87ABCD
i valori assegnati alle variabili I e CHAR sono rispettivamente il numero intero
1986 e la stringa di caratteri 1986/87.
Esempio 13.45. Sia A un vettore reale i cui primi M elementi A(l), con l ~ I ~ M
ed M assegnato, sono definiti da A(l) = 2 • I + 0.5. Si vogliono stampare i sud
detti elementi, facendo precedere il valore di ciascuno di essi dal suo nome A( I),
A(2), ecc.; inoltre il valore di un elemento deve essere separato dal nome del
successivo mediante una virgola.
Consideriamo a tale scopo la seguente istruzione dove si suppone che il numero
di unità 2 identifichi la stampante e che sia M ~ 99:
WRITE (2,3) M, (I, A(I), I = I, M)3 FORMAT (22X, 'STAMPAvDElvPRIMI', 12, 'vELEMENTIVDlvA'//
• 6 (IX, 'A(', 12, ') =', FS.! : '.')
Per effetto di tale frase vengono create una o più righe di stampa, ciascuna
contenente i valori di 6 elementi di A secondo il formato richiesto; osserviamo chela presenza del descrittore fra F5.1 e permette di non stampare la vir
gola dopo il valore dell'ultimo elemento. Le righe di stampa contenenti i valori de
gli elementi di A sono precedute da una riga in cui si segnala il numero di elementi
stampati. In fig. 13.11 si riportano le righe di stampa ottenute per M = 6 e M = IO
STAMPA DEI PRIMI 6 ELEMENTI DI A
Al 1)= 2.5. Al 2)= 4.5. Al 3)= 6.5, Al 4)= 8.5. Al 5)= 10.5. Al 6)= 12.5
STAMPA DEI PRIMI lO ELEMENTI DI A
Al 1)= 2.5. Al 2)= 4.5. Al )= 6.5. Al 4)= 8.5, Al 5)= 10.5. Al 6)= 12.5.Al 7)= 14.5. Al 8)= 16.5. Al 9)= 18.5. AllO}= 20.5
Figura 13.11. Stampe relative all'esempio 13.45.
J descrittori BN e BZ
I descrittori non ripetibili BN e BZ possono essere usati per stabilire una con
venzione sull'interpretazione dei caratteri blank successivi al primo non blank
nei campi numerici dei records di ingresso (cfr. § 13.3). Più precisamente, se in
una specificazione di formato viene incontrato il descrittore BN o BZ tutti i blanks
presenti nelle posizioni suddette nei campi individuati dai successivi descrittori
232 233
Se il descrittore è Dw.d, Ew.d, oppure Ew.dEc, il valore di s deve soddisfare la re
lazione - d < s";; d + l. Il campo prodotto in uscita se - d < s";; O ha la forma
seguente
Il descrittore sP
Il descrittore sP, dove s è una costante intera, specifica un fattore di scalache influisce sulle modalità di rappresentazione esterna dei numeri reali che
verranno trasmessi successivamente durante l'operazione di I/O. L'effetto di un
descrittore sP resta valido anche nel caso di riscansione della specificazione di
formato. In assenza di descrittori sP si intende che il fattore di scala è zero.
In ingresso un fattore di scala s diverso da zero influisce soltanto sull'interpre
tazione dei numeri reali che sono scritti sul record in una forma senza esponente;
infatti se y è il numero scritto nel campo esso viene interpretato come y l O-s.
Per esemplificare quanto detto supponiamo di avere nel record di ingresso la strin
ga 1525.; con la specificazione di formato (2P, FIO.O) la stringa viene interpretata
come il numero reale 1525.10- 2, ovvero 15.25, mentre con la specificazione
(- 2P, FIO.O) viene interpretata come 1525.10+ 2, ovvero 152500.
In uscita l'influenza di un fattore di scala diverso da zero varia a seconda del
descrittore ripetibile associato al campo su cui il numero reale deve essere rap
presentato. Se il descrittore è Fw.d, allora il valore da scrivere nel campo è ot
tenuto moltiplicando per 10s il numero che deriva dalla conversione in base dieci
del dato. Così, ad esempio, il valore - 4.3522 viene riprodotto come
di tipo numerico vengono ignorati o considerati zero rispettivamente. Ricordiamo
che in assenza di tali descrittori, i caratteri blank di cui stiamo trattando vengono
ignorati o considerati zero, a seconda della convenzione in atto per l'unità di in
gresso usata (cfr. cap. 18). Osserviamo che l'effetto dei descrittori BN e BZ resta
valido anche quando la specificazione di formato viene nuovamente scandita. Ov
viamente l'effetto di un descrittore BN viene annullato se, nel seguito della scansione, si incontra un descrittore BZ, e viceversa.
Esempio 13.46. Se il record
12 vvvvvv 0.5E2 vl2 vvvvvv 0.5E2
viene letto con la frase
READ '(BZ, 14, FIO.5, BN, 14, FIO.5)', I, A, J, B
i valori assegnati alle variabili I, A, J, B sono rispettivamente 1200, 0.5 x 102°,12, 0.5 x 102•
I descrittori S, SP, SS
l descrittori S, SP, SS possono essere usati in una specificazione di formato
relativa ad una istruzione di uscita per stabilire una convenzione riguardo alla
presenza o meno del segno + nella rappresentazione esterna dei numeri positivi.
In particolare, il descrittore SP indica che, in tutti i campi in cui deve essere rap
presentato un numero positivo individuati dai successivi descrittori di tipo nume
rico, deve essere presente il segno +; il descrittore SS indica che tale segno deve es
sere omesso; infine il descrittore S indica che deve essere restaurata la convenzione
adottata dal sistema di calcolo. Lo standard F77 specifica che l'effetto di un
descrittore S, SP, SS resta valido anche in caso di riscansione della specificazionedi formato. (13.3)
vvv-4.3522
v-435.2200
vvvv-.0435
se la specificazione di formato è
se la specificazione di formato è
se la specificazione di formato è
(FIOA)
(2P, FIOA)
(- 2P, FIOA).
Esempio 13.47. Se le variabili LI, L2, L3 valgono rispettivamente 30, 31, 32,la frase
con k = Isi cifre uguali a zero dopo il punto decimale; se invece è O< s";; d + l,
allora il campo prodotto ha la forma seguente
PRINT '(IX, SP, 13, SS, 13, S,B)', LI, L2, L3(13.4)
determina la creazione del seguente record:
v+30v31v32
se il sistema prevede di non riprodurre il segno +; altrimenti si ottiene il record:
v + 30v3I+32.
l
In (13.3) e (13.4) exp ha una delle forme previste per i descrittori Ew.d,
Dw.d ed Ew.dEc. Le cifre ai e il valore dell'esponente b espresso in exp in (13.3)
e (13.4) vanno così interpretati: il valore espresso in base dieci del dato in memo
ria è, a meno di arrotondamenti sull'ultima cifra decimale, ± 0.0 ... Dal a2 •••
ad - k x lOb e ± al" . as .as+ I ... ad+ 1 x IOb rispettivamente.
234 235
Esercizi
13.1. Individuare gli errori presenti nelle seguenti frasi:
READ '(3AIO)', CHAR (:10), CHAR (16:25), CHAR (26:)
READ '(5(A3, 13»', (CHAR (I : I + 2). LOC(I), I = 1,13,3).
vvlvv2vv3vv4vv5vv6vv7vv8vv9vvO
21 FORMAT (13, F8.1, 14)
13.2 Data l'istruzione FORMAT:
PRINT 234, N, «A(I. J), J = 1. N), I = l, N)
FORMAT (IX, 'NUMEROvDl vEQUAZIONI:'. 14//
IX, 'MATRICEvDELvSISTEMA:v'/5(2X, EI3.6»•234
13.5 Scrivere le liste di I/O che comprendono:
a) tutti gli elementi di un vettore V di lunghezza 30;
b) gli elementi di posto pari di un vettore v di lunghezza 30;
c) gli elementi della seconda colonna di una matrice, TAV, di 8 righe e I Ocolonne;
d) gli elementi di indici (1,1) di una matrice quadrata TAV con
N - M + l ~ I ~ N, N - M + I ~ J ~ N dove M < N;
e) gli elementi della I-esima riga di una matrice A di N righe ed N colonne.
13.4 Specificare Quanti records vengono prodotti con le seguenti istruzioni diuscita se N vale lO:
13.6 Scrivere una opportuna frase di ingresso/uscita guidata dalla lista per ognu
na delle seguenti richieste:
a) leggere un valore di N e i primi N elementi del vettore V il cui dichiaratore sia V(O : lO)
b) leggere un valore di N e la sottostringa costituita dagli ultimi N caratteridi una variabile carattere;
c) scrivere gli elementi della J-esima colonna di una matrice MAT ognuno
moltiplicato per il corrispondente indice di riga, supponendo che il dichiaratore della matrice sia MAT ( IO, IO);
d) leggere le righe di ordine dispari di ciascun piano della variabile dimen
sionata TRIO, il cui dichiaratore sia TRIO (9, IO, 4);
e) scrivere le potenze del 2 da 23 a 215 ;
f) leggere le righe di indici l, 4, 7, lO della matrice STR il cui dichiaratoresia STR (O: ro, O : 5);
g) scrivere in ordine inverso gli elementi di un vettore V il cui dichiaratoresia V(20).
13.7 Scrivere alcune possibili istruzioni che permettono di stam pare il messaggio
21, (N(I), X(I), M(I), I = l, lO)
21, N(I), X(5), M(7)
21, Kl
21, Kl, ALFA
21, (N(I), X(I), M(I), N(I + I), X(I + I), M(I + 1).1 = 2,9)
21, «L(I, 1), Y(I, 1), K(I, 1), I = l, ioi, J = l, lO).
READ
READ
READ
READ
READ
READ
READ., X, Y, X + Y
READ ., '(513)', N, M
READ '(214, 2E13.6)', X, Y, K, J
READ., (X, Y)
READ ., A(I), I = l, N
READ (6,77) «A(I, 1), I = l, N) J = l, N)
READ (6,77) «A(I, 1) I = I, N, J = l, N)
PRINT. X, Y, X + Y
PRINT (5, '(2 D22.15)') DI, D2
WRITE (5, '(2 D22.15)'), D L D2
PRINT '(1 X, G13.5)', (X .. 2, X = 1.5)PRINT, 250, X, Y
PRINT (., .) X, Y
WRITE (., 15) L +M
specificare quanti records vengono letti con ognunadelle seguenti frasi:
specificare il valore attribuito a ciascun elemento della lista delle seguenti
istruzioni di ingresso nell'ipotesi che i caratteri blank nei campi numericisiano interpretati come cifre zero:
13.3 Sia LOC un vettore intero di 30 elementi e CHAR una variabile carattere
di lunghezza 30. Supponendo di leggere il seguente record di ingresso:
READ '(1013)', (LOC(I), I = 1,30)
READ '(516)', (LOC(I), I = 1,30)
LAvSOLUZIONEvDELvPROBLEMAvE':v
supponendo che la stampante sia associata al numero di unità 6.
236
13.8 Scrivere una frase FO RMAT opportuna per ciascuna delle seguen ti istru
zioni READ, in base alle descrizioni dei records specificate per ognuna diesse:
a) READ 1200, A, B, C, D
Ciascun record contiene nelle posizioni fra la Il-esima e la 20-esima com
prese un numero reale in cui è presente un punto frazionario;
b) READ 1200, A, B, C, D, E, F, G, D
Ciascun record è composto da quattro campi di ampiezza 8; in ogni campo
è scritto un numero reale sotto forma di costante intera senza punto deci
male, ed ogni numero è scritto nelle posizioni più a destra del campo.
13.9. Scrivere una frase FORMAT opportuna per ciascuna delle seguenti istruzioni di uscita, in base alle descrizioni dei records specificate:a) WRlTE (5, 1300) A, B. C, D
I dati devono essere stampati m campi di ampiezza 20 nella forma senza
esponente con due cifre dopo il punto decimale. Ogni dato deve esserestampato su una riga a distanza di due righe dalla precedente;
b) WRITE (5, 1300) A, B, C, D
I dati devono essere scritti su una sola riga, ciascuno in un campo di ampiez
za 13, nella forma con esponente con 6 cifre di mantissa. 11 primo datodeve essere preceduto dalla stringa di caratteri A = ~ , il secondo da B = ~ ,e così via:
c) WRlTE (5, 1400) I, U, K, V, W, J, Z, Y, X
I dati devono essere scritti su tre linee. La prima linea deve contenere i
primi due dati, la seconda i tre successivi e la terza gli ultimi quattro. Ogni
numero intero deve essere scritto in un campo di ampiezza 6, mentre ogni
numero reale deve essere scritto in un campo di ampiezza lO con esponente
e 3 cifre di mantissa. Due campi consecutivi devono essere separati da 3caratteri blank;
d) WRITE (5, 1500) I, J, (X(l), I = l, lO)
I primi due dati devono essere scritti su una riga in campi di ampiezza lO.
Deve poi seguire una riga contenente la stringa *** VETTORE~X *** apartire dalla Il-esima posizione. I successivi dati devono essere stampati 5
per riga, in campi consecutivi di ampiezza 20 separati da l carattere blank,nella forma con esponente con 13 cifre di mantissa.
237
13.10 Sia CAR una variabile dimensionata carattere, ogni elemento della quale
ha lunghezza 4. Scrivere una frase di uscita che permetta di stampare glielementi di CAR indicati dalla lista con DO-implicito
«CAR(I, 1), J = l, 8), I = l, 8)
su un «quadrato» così strutturato: ciascuna linea contiene 8 valori ognuno
separato dal successivo mediante 6 caratteri blank; fra una riga e l'altra ci
sono 3 linee vuote. L'intero quadrato deve essere preceduto dal titolo
QUADRATO~DI~LATO~8centrato rispetto al quadrato stesso.
13.11 Scrivere una frase di uscita che permetta di stampare la tavola pitagorica
da 5 a 9; gli elementi della tavola devono essere scritti in campi di ampiez
za 3 e distanziati l'uno dall'altro mediante 2 caratteri blank. La tavola deve
essere preceduta dal titolo TAVOLA~PlTAGORICA~DA~5~A~9cen
trato rispetto alla tavola stessa.
!i
illiIlII1
14Definizione e utilizzazionedei sottoprogrammi
14.1. Programma principale e sottoprogrammi
Nei capitoli precedenti è stata sottolineata la notevole utilità delle funzioni
intrinseche che permettono di eseguire operazioni non elementari di uso molto
comune. D'altra parte è possibile evidenziare diverse classi di problemi quali, ad
esempio, la risoluzione dei sistemi lineari algebrici o il calcolo degli autovalori
di una matrice la cui risoluzione è richiesta comunemente nelle applicazioni
scientifiche. Gli algoritmi risolutivi di questi problemi possono essere trascritti
in FORTRAN in modo da costituire unità di programma distinte dette sottopro
C!~rrzmi che vengono autonomamente compilate e che, essendo identificate me
diante nomi simbolici, possono essere utilizzate da qualunque programma. Per
tanto, un programma FORTRAN è generalmente costituito da più unità: una
di esse, detta prozramma prinEipa/e. gestisce l'utilizzazione di tutte le altre e non
viene utilizzata da nessun'altra unità; le altre, i sottoprograrnmi, sono invece uti
lizzate da una o più unità di programma e possono a loro volta utilizzare altri
sottoprogrammi. Per esemplificare, in modo semplice, quanto detto si consideri
l'esempio seguente:
Esempio 14.1. N studenti di un corso di laurea hanno sostenuto M esami ciascuno.
Si vuoI calcolare e stampare il voto medio riportato da ogni studente; inoltre, indi
cata con mi la media con~eguita dall'i-esimo studente, si vuole calcolare e stampa-
re la media globale p. = (1: m.)/N.i= l I
Per risolvere questo problema si utilizza, evidentemente, il calcolo della media
aritmetica di un certo numero di valori noti. II procedimento per calcolare la me
dia è infatti utilizzato N + I volte: le prime N per determinare il voto medio midi ciascuno studente, l'ultima per determinare la media globale p.. Indicate con vi'I ~ i ~ M, le votazioni riportate da ogni studente, un algoritmo risolutivo di que
sto problema può essere formulato come mostra la fig. 14.1 nella quale l'algo
ritmo 14.1 fa riferimento (N + 1) volte all'algoritmo 14.2 utilizzandolo, ogni vol
ta, con dati diversi: quando serve per calcolare la media dei voti riportati da uno
240
Algoritmo 14.1
1. Leggi:M, N2. Per i = l, ..., N
2.1. Leggi: vl'·· ., vM2.2. Utilizza l'algontmo 14.2 per calcolare m.
3. Utilizza l'algoritmo 14.2 per calcolare Il. l
4. Scrivi: ml' .. " mN' Il.S. Stop
Algoritmo 14.2
1. Dati: n, al' ..., an2. Poni m =03. Peri= l, ..., n
l. Poni m = m + ai4. Poni m = m/nS. Risultato: m6. Stop
Figura 14.1. Algoritmo risolutivo deU'esempio 14.1.
studente, i suoi dati n, al' a2 , ... , an corrispondono, rispettivamente, al nu
mero M degli esami ed alle votazioni vI' v2' ..., vM riportate; quando invece
esso è utilizzato per calcolare la media Il, allora deve usare come dati i valori
N, mI' m2, ..., mN" Per questo motivo, l'istruzione di lettura dei dati è sostituita
nell'algoritmo 14.2 da una frase che mette in evidenza soltanto quali e quanti
valori devono essere acquisiti mentre l'istruzione di scrittura è stata sostituita
da una frase che mette in evidenza il risultato fornito al termine dell'algoritmo.
La realizzazione in FORTRAN dei due algoritmi è il programma richiesto dal
problema; esso risulta costituito dalle istruzioni che traducono l'algoritmo 14.1 e
che costituiscono il programma principale e dalle istruzioni relative all'algoritmo14.2 che costituiscono il sottoprogramma.
Come è già stato accennato, ogni sottoprogramma può utilizzare più sottopro
grammi e, a sua volta, può essere utilizzato da altre unità di programma. L'organizzazione di un programma FORTRAN può essere pertanto molto complessa
e, in ogni caso, è sempre estremamente utile sapere come le diverse unità di programma interagiscono tra di loro. La composizione e l'organizzazione di un programma possono essere visualizzate graficamente mediante l'albero delle chiamate(1) che è costituito da più blocchi uniti da frecce: ciascun blocco rappresenta
(I) Questo nome deriva dalla consuetudine di indicare con chiamata di un sottoprogranuuala sua utilizzazione.
241
una unità di programma ed il nome dell'unità è specificato all'interno del blocco;se l'unità di programma chiama altre unità, il blocco che la rappresenta è unito a
tutti i blocchi che rappresentano le unità utilizzate mediante frecce dirette verso
l'unità chiamata. In fig. 14.2 è riportato un albero delle chiamate che mette inevidenza l'organizzazione di un programma costituito da otto unità di programma:un programma principale e sette sottoprogrammi. 11 programma principale utilizzail sottoprogramma NOME l il quale chiama tre sottoprogrammi: NOME2, NOME3e NOME4. Il sottoprogramma NOME2 chiama a sua volta NOME3 mentre l'unitàNOME4 utilizza i due sottoprogrammi NOME5 e NOME2. Infine, NOME5 utilizza
NOME 6 e NOME7 mentre NOME2 richiama NOME6.E' importante ricordare che il FORTRAN non è un linguaggio ricorsivo e, per-
1111 tant~ un sottoprogramma no.-!!.pyò richiamare se stesso in nes~~ ~llO_do, n~~i " .f(, attraverso l'utilizzazione di altri sottoprogrammi. Sono pertanto situazioni proibi- il i \ (
te quelle esemplificate in fig. 14.3. .
L'albero delle chiamate permette quindi di evidenziare quali e quante unitàdi programma devono essere disponibili per produrre il programma in forma
eseguibile. L'esecuzione del programma inizia sempre con quella del programmaprincipale. Ciascun sottoprogramma viene eseguito in corrispondenza di un'oppor
tuna istruzione mediante la quale vengono fomite al sottoprogramma le informa
zioni necessarie alla sua esecuzione. Il momento in cui si effettua lo scambio di
informazioni necessarie alla esecuzione di un sottoprogramma verrà detto (l!tiva
~. del sottoprogramma e diremo invece uscita dal sottoprogramma il momentoin cui, terminata l'esecuzione del sottoprogramma, i risultati da esso ottenuti
sono disponibili per l'unità chiamante (detta anche unità attivante). L'esecuzione
di ogni unità di programma avviene quindi in modo sequenziale fino a che non si
incontra una frase che provoca l'attivazione di un sottoprogramma. Per effetto di
Figura 14.2. Esempio di albero delle chiamate.
242 243
INOME l H NOME 11la fine dell'esecuzione del sottoprogramma, il corpo del sottoprogramma evidenziato in fig. 14.4 dal blocco tratteggiato.
Figura 14.3. Esempi di situazioni ricorsive proibite in FORTRAN.
14.2. La prima istruzione di un sottoprogramma
Oltre alle funzioni intrinseche, in F77 sono previsti sottoprogrammi di tipo
SUBROUTINE, FUNCTION e BLOCK DATA che si distinguono mediante la
parola chiave specificata nella loro frase iniziale. In questa frase viene anche indi
cato il nome che individua il sottoprogramma distinguendolo dalle altre unità che
costituiscono un programma. Un altro compito importante spesso riservato alla
prima frase di un sottoprogramma è quello di permettere lo scambio di informazioni con l'unità di programma chiamante. Questo scambio può infatti essere
realizzato mediante l'associazione di due liste di nomi: quella degli argomenti attuali, specificata nella frase che permette l'attivazione del sottoprogramma, e
quella degli argomenti muti specificata nella prima istruzione del sottoprogram
ma. In generale diremo che un argomento muto ed un argomento attuale sono
associati quando identificano la stessa informazione. L'associazione tra le due li
ste di argo~~~_~_a~i~n_~_~l momento dell'attivazione del sottoprogrammaquandoil primoa!gomento ~tt~~le_è associato al primo argomento muto, il secondo ar
gomento attuale al secondo. argomento muto e così via fino all'ultimo argo
mento attuiiie che-è asso~t;to alhìltlmo argomento muto. Facendo riferimento al
IYesempÌo 14.] del paragrafo precedente, un sottoprogramma che calcola la media
m di n valori noti al' a2, ..., an basandosi sull'algoritmo ]4.2 deve iniziare con
una frase che ne specifica il nome e che può contenere, quali argomenti muti, i
nomi che identificano i dati n, al' ... , an ed il risultato m. L'attivazione di questo
sottoprogramma avverrà utilizzando in modo opportuno il suo nome e facendo
corrispondere alla lista degli argomenti muti quella degli argomenti attuali nella
quale devono essere specificati i nomi che identificano, nell'unità di programma
chiamante, gli effettivi valori di cui si vuoi calcolare la media. AI momento della
attivazione del sottoprogramma gli argomenti muti vengono associati a quelli at
tuali ed il sottoprogramma viene pertanto eseguito usando come dati i valori identificati dagli argomenti attuali.
Quanto detto mette in evidenza che una corretta utilizzazione di un sottoprogramrna non può prescindere dalla conoscenza del significato degli argomenti
muti. In particolare useremo talvolta il termine argomento muto di ingresso per
mettere in evidenza il fatto che un argomento identifica una informazione tra
smessa dall'unità di programma attivante al sottoprogramma; indicheremo invece
con il termine argomenti muti di uscita gli argomenti che identificano le informa
zioni definite all'interno del sottoprogramma che vengono trasmesse in uscita al
l'unità di programma chiamante. Evidentemente i risultati forniti da un sotto-
Unità di programmachiamata
Blocco diistruzioni
Blocco diistruzioni
Unità di programmochiamante
Riferimento al sottoprogramma
Figura 14.4. Trasferimento del controUo dell'esecuzione tra unità diprogramma chiamante e unità di programma chiamata.
questa frase il controllo dell'esecuzione è trasterito dall'unità attivante a quella at
tivata fino al momento dell'uscita dal sottoprogramma quando l'unità chiamante
riprende il controllo dell'esecuzione. Quanto detto può essere sinteticamente sche
matizzato come in fig. 14.4 dove il verso delle frecce indica il flusso di esecuzione
e istruzione di ritorno sta ad indicare una istruzione che determina la fine dell'e
secuzione del sottoprogramma ed il trasferimento del controllo alla unità chia
mante. Si osservi che, mentre la frase iniziale di un sottoprogramma è unica,
quella che determina il ritorno all'unità chiamante può non essere unica esatta
mente come in un programma principale può non essere unica la frase STOP che
determina la fine della sua esecuzione. Le situazioni che determinano il ritorno
all'unità di programma chiamante sono descritte ne] blocco di istruzioni che
seguono la prima frase e che costituiscono, insieme con le frasi che determinano
244
programma fanno parte degli argomenti di uscita. Si osservi che un argomentopuò essere sia di ingresso che di uscita quando identifica una informazione che,trasmessa come dato dall'unità di programma attivante, viene poi modificata
durante l'esecuzione del sottoprogramma.Nel seguito useremo talvolta i termini parametri attuali e parametri muti in
luogo di argomenti attuali e argomenti muti rispettivamente.
14.3. Il corpo di un sottoprogramma e l'istruzione RETURN
Il corpo di un sottoprogramma è costituito da tutte le istruzioni che seguono
la prima. Esso deve c:ontenere tutte.le.frasi ir/(!iWJ~n§!lbili per una corretta ed autonoma compi/azione del sottoprogramma. In particolare, qualorasian()uTilizz-ati
no~i- di v~riabiledimensionata~-d;~;o essere presenti nel corpo del sottopro
gramma le opportune frasi di specificazione che possono riguardare anche nomi
presenti nella lista degli argomenti muti. Analogamente, possono seguire la prima
frase tutte le istruzioni di specificazione di tipo. lLcorpo di un sottoprogramma
de~nlln.unque terminare con t'tstrustane.~p il cui ~i~nifica!~p!!PtQ quellB
di se~~alare la fine delle istruzioni che costituiscono una unità di programma.
--Si osservi che tutt~i '!~~L~Iy~iiabf1eutii1Zzati in un qualunq~~Qn9PfOgramma-so-noloc~li n~l senso che ~~ni_!l~~~p~~ essere ~sa~o in lJn~tà di programma
distinte con significati completamente diversi.• ~A__.__ __
Comé è stato evidenziato anche in fig. 14.4 il corpo del sottoprogramma deve
contenere almeno una istruzione che ne interrompe l'esecuzione e trasferisce il
controllo all'unità chiamante. Tale istruzione, nella sua forma più semplice, è
costituita dalla sola parola chiave
RETURN
Un'altra forma di questa istruzione, utilizzabile però soltanto nei sottoprogrammi
SUBROUTINE. sarà vista nel capitolo seguente.
Si osservi che in F77 la sequenza di istruzioni
RETURN
END
è equivalente alla sola frase
END
Pertanto in F77 un sottoprogramma può non contenere la frase RETURN che in
vece era obbligatoria in F66. Come è già stato osservato il ruolo della frase
RETURN in un sottoprogramma è analogo a quello della istruzione STOP nel
programma principale. A tale proposito si osservi che, mentre la frase RETURN
245
non deve far parte di un programma principale, l'istruzione STOP può essereutilizzata anche in un sottoprogramma ed il suo effetto è quello di interromperel'esecuzione del sottoprogramma senza provocare il rientro nell'unità di programma chiamante. In altri termini, l'esecuzione di una frase STOP all'interno di un
sottoprogramma causa la fine dell'esecuzione dell'intero programma.
14.4. I sottoprogrammi SUBROUTlNE e la frase CALL
I sottoprogrammi SUBROUTINE permettono di realizzare qualunque algo
ritmo il cui risultato può essere costituito da più di un valore.
La prima istruzione
La prima frase di un sottoprogramma SUBROUTlNE ha la forma seguente:
SUBROUTINE nome (m" 01 2, .. " mn )
dove:• SUBROUTINE è la parola chiave che identifica la frase;• nome è un nome simbolico e costituisce il nome di sottoprogramma; esso
non deve comparzre_!!! ~~~~_istru~~~~~_erc?~p~clel sotto,,-rc!R~rnm,!; ----• mI' m2, ..., m
nsono gli argomenti muti del sottoprogramma. Ogni argomento
muto può essere un nome di variabile, un nome di variabile dimensionata un nome di sottoprogra~ma, un asterisco. Gli argomenti muti costituiti da no'm~bolici devono essere tutti distinti.
Un sottoprogramma SUBROUTINE può non avere argomenti muti; in questo
caso la prima istruzione può assumere una delle forme seguenti:
SUBROUTlNE nome tSUBROUTlNE nome
Esempio 14.2. Sono sin tatticamente corrette le istruzioni:
SUBROUTINE SIST (A, N, X, Y)SUBROUTINE COPIA(A, B)SUBROUTINE UN (XPl, XM2,SIGMA,*, -. *)SUBROUTINE STAMPA
Sono invece sbagliate le seguenti:
SUBROUTINE TRASP(A(l), N, X)SUBROUTINE LISTA(X, Y, 5)SUBROUTINE TEST (A, B, A + B)SUBROUTINE ESPER (X(4:), PAR)
Queste frasi infatti contengono, rispettivamente, un nome di elemento di varia
bile dimensionata, una costante, una espressione, un nome di sottostringa.
!,I!
, I
246
Esempio 14.3. Il sottoprogramrna MAXMIN di fig. 14.5 permette di calcolare
il massimo ed il minimo fra tre numeri reali a, b, c. Gli argomenti muti del sotto
programma sono A, B, C, MAX, MIN: i primi tre sono i nomi usati nel sottopro
gramma per indicare le tre quantità a, b e c rispettivamente, mentre MAX e MIN
sono i nomi usati per indicare il massimo ed il minimo.
Confrontando il sottoprogramma di fig. 14.5 con il programma principale del
l'esempio 9.12 si può notare che la frase STOP è stata sostituita dalla RETURN
e che le frasi di ingresso/uscita sono state eliminate in quanto le informazioni
relative ai dati e ai risultati vengono trasmesse tramite la lista degli argornenn
muti.
SUBROUTINE MAXMIN (A, B, C, MAX,MIN)REAL A, B, C, MAX,MINIF (A.GT.B) THEN
MAX=AELSE
MAX=BENDIFIF (C.GT.MAX) THEN
MAX=CENDIFIF (A.GT.B) THEN
MIN=BELSE
MIN=AENDIFIF (C.LT.MIN) THEN
MIN=CENDIFRETURNEND
Figura 14.5. Sottoprogramma per il calcolo del massimo e del minimo fra tre valori reali.
Esempio 14.4. Si vuole scrivere un sottoprogramrna che permetta di calcolare la
radice quadrata di un numero positivo x usando l'algoritmo di fig. 10.6.
L'esempio 10.14 fornisce un programma principale che risolve questo stesso
problema e che prevede operazioni di scrittura diverse per evidenziare il risultato.
Il sottoprogramma che viene ora richiesto può essere realizzato in modo da tra-
247
smettere in uscita tutte le informazioni relative al risultato ottenuto affinché l'uni
tà di programma chiamante possa utilizzare tali informazioni per eseguire qualun
que tipo di operazione sul risultato, comprese quelle di scrittura previste nell'e
sempio 10.14. Per informare l'unità chiamante sul tipo di risultato ottenuto si
può prevedere, tra le informazioni in uscita, il valore di una variabile IND che nel
corpo del sottoprogramma viene posta uguale a zero se è verificata la condizione
1m2 - x I.,;;; G, uguale ad l in caso contrario. Il sottoprogramma richiesto è stato
chiamato RADQ, è di tipo SUBROUTINE ed utilizza nove argomenti muti il
cui significato è specificato mediante opportune frasi di commento.
ISUBROUTINE RADQ(X, SIGMA,NIT, SX, DX,IND, RAD, ERR, IT)
C SOTTOPROGRAMMA PER IL CALCOLODELLA RADICEQUADRATA DI X > OC ARGOMENTI MUTIDI INGRESSO:C X : NUMERO POSITIVODI CUI SI VUOL CALCOLARE LA RADICEC SIGMA: TOLLERANZAPER IL CRITERIO DI ARRESTOC NIT: NUMEROMASSIMO DI ITERAZIONIC ARGOMENTI MUTI DlINGRESSO/USCITA:C SX IN INGRESSO: NUMERO REALE MINOREDI XC DX IN INGRESSO: NUMERO REALE MAGGIORE DI XC AD OGNI ITERAZIONE IL VALORE DI SX O DI DX VIENE MODIFICATOC ARGOMENTI MUTI DI USCITA:C IND: VARIABILE DI CONTROLLO CON I SEGUENTIVALORIC = OSE IL CRITERIO DI ARRESTO E' SODDlSFATTOC = I ALTRIMENTIC RAD: PER IND = OE' L'APPROSSIMAZIONE DELLA RADICE DI XC ERR : PER IND = OE' L'ERRORE ABS(RAD .. 2 - X)C IT : PER IND = OE' IL NUMERO DI ITERAZIONI ESEGUITEC PER IND = l I VALORI DI RAD, ERR, IT SONO QUELLI RELATIVIC ALL'ULTIMA ITERAZIONEESEGUITA.
DO 150 IT = l, NITRAD = SX + 0.5 • (DX - SX)ERR = ABS(RAD .. 2 - X)IF (ERR.LE.SIGMA) THEN
IND=ORETURN
ELSE IF (RAD .. 2.GT.x) THENDX=RAD
ELSESX = RAD
END IF150 CONTINUE
IND = lEND
Esempio 14.5. L'algoritmo di fig. 14.6 risolve l'equazione ax 2 + bx + c = O, con
a *" O. Nell'algoritmo si considera nullo qualunque valore del discriminante
Riferimento ad un sottoprogramma SUBROUTlNE
Un sottoprogramma SUBROUTINE viene chiamato mediante una frase esegui
bile la cui forma è la seguente:
dove:
• CALL è la parola chiave che identifica la frase;
• nome è il nome del sottoprogramma che si vuole attivare;
• al' a2, ..., an sono gli argomenti attuali ciascuno dei quali può essere costitui
to da un nome di variabile, un nome di variabile dimensionata, un'espressione, un
nome di un altro sottoprogramma, uno specificatore di ritorno alternativo (cfr.
cap. 15). Il numero !kg!i argomenti attuali deve coincidere con quello degli argomenti muti del ~~.!!Q.Q!og~~m-ma-chiamato. _- -- - - __o - ..-- - ---- ------ .-.-.
Se-if-sottoprogramma chiamato non ha argomenti muti la frase CALL può
avere una delle forme seguenti:
CALL nome ( )
CALL nomeL'effetto dell'esecuzione di una frase CALL è quello di attivare il sottopro
gramma il cui nome è specificato nella frase e di riprendere il controllo dell'esecuzione al momento dell'uscita dal sottoprogramma.
248
1. Dati: a"* O, b, c, e > O2. Poni 6 = b2
- 4 ac3. SeI61";f,allora: poni ind e 1;
poni XI = - b/2a;poni X2 = XI;
esegui 4.altrimenti: se 6> e, allora: poni ind = 2;
se b < O,allora: poni s = - 1altrimenti: poni s =+ 1
poni XI =- (b + s -Ji.)/2a;poni X2 = c/(a xj );esegui 4.
altrimenti: poni ind = O;poni XI =- b/(2a);poni X2 =....et;/(2a),esegui 4.
4. Risultati: ind, XI, X2
5. Stop.
Figura 14.6. Algoritmo per la risoluzione di 02 + bx + c = O con a"* O.
t:. = b2 - 4 ac tale che It:.IE;;; f, con f> Oassegnato dipendente dalla precisione
di macchina; inoltre, t:. è considerato positivo se t:. > e e negativo se t:. < - f. Al
termine dell'algoritmo i risultati sono i seguenti:
ind = O se l'equazione non ha radici reali ovvero se t:. < O;
ind = l se l'equazione ha radici reali coincidenti ovvero se t:. = O;
ind = 2 se l'equazione ha radici reali distinte ovvero se Is> O;
Xl e x2 sono le radici dell'equazione se ind = l oppure ind = 2, mentre se
ind = O esse sono rispettivamente la parte reale e quella immaginaria delle due
radici complesse coniugate Xl ± i x2·
Si osservi che le eventuali radici reali e distinte dell'equazione vengono calcolate
secondo le formule
Xl = - (b + sign (b) Vi.)/2:+
x2 = c/(a Xl)
per limitare la propagazione degli errori di arrotondamento [lO].
Basandosi sull'algoritmo di fig. 14.6 si può scrivere il seguente sottoprogramma,
SOLV2, i cui argomenti muti A, B, C, EPS, X l, X2, IND rappresentano rispet
tivamente a, b, c, e, xl' x2 ' ind.
l
cC
SUBROUTINE SOLV2 (A, B, C, EPS! Xl, X2, IND)RISOLUZIONE DI UN'EQUAZIONE DI SECONDO GRADOA • X u 2 + B • X + C = O, CON A DIVERSO DA ZERODELTA=Bu2-4.• A.CIF (ABS(DELTA).LE.EPS) THEN
IND = 1XI =-0.5. B/AX2 =Xl
ELSE IF (DELTA.GT.EPS) THENIND = 2 \IF (B.LT.O.) THEN
S=-1.ELSE
S=+1.ENDIFXI = - 0.5. (B + S. SQRT(DELTA»/AX2 = C/(A. XI)
ELSEIND = OXI =-0.5. B/AX2 = + 0.5. SQRT (- DELTA)/A
END IFRETURNEND
249
250 251
SUBROUTINE PROVA (X, N, Y)
SUBROUTINE RADQ (X, SIGMA, NIT, SX, DX, IND, RAD, ERR, IT)
Esempio 14~ 6. Dato il sottoprogramma definito dalla frase
Il programma richiesto può essere il seguente:
PROGRAM VALOR]C CALCOLO DE] VALORI l/SQRT(N), N = 2, ... ,50C SI UT]L1ZZA ]L SOTTOPROGRAMMA RADQC NEL PROGRAMMA PRINCIPALE GLI ARGOMENTI ATTUALIC HANNO GLI STESS] NOMI DE] CORR]SPONDENT] ARGOMENTIC MUT] AD ECCEZ]ONE DI X AL QUALE CORRISPONDE RN
READ ., S]GMA, NITPRINT 1000, S]GMA, NlTDO 100 N = 2, SORN=NSX= l.DX = N/2. + l. ICALL RADQ (RN, S]GM.\, NlT, SX, DX, IND, RAD, ERR,lT)IF (IND.EQ.l) THEN
PRINT 1500, NELSE
VAL= l./RADPRINT ]600, N, VAL, ERR, lT
END ]F100 CONTINUE
STOP1000 FORMAT (lX, 'TOLLERANZA:', EI3.6/
l IX, 'NUMERO MASSIMO DI lTERAZIONI:', BI)1500 FORMAT (lX,'PER N =',12/
l IX, 'NON E" SODDISFATTO IL CRITER]O DI ARRESTO')1600 FORMAT (lX,'PER N =', ]2/
1 ]X, 'VALORE CALCOLATO:', E13.6/2 IX, 'ERRORE COMMESSO:', E13.6/3 IX, 'NUMERO DI ITERAZ]ONI ESEGUITE:', 13).
END
Si osservi che il sottoprogramma RADQ utilizza un argomento di tipo reale, X,
per indicare la quantità di cui si vuoi determinare la radice quadrata. Ad X deve
quindi corrispondere un argomento attuale di tipo reale; da qui la necessità diassegnare, prima di ogni attivazione del sottoprogramma, alla variabile reale RN
il valore di N. Gli altri argomenti muti utilizzati dal sottoprogramrna corrispondo
no, nel programma chiamante, ad argomenti attuali che hanno il loro stesso nome
e, mentre i valori di SIGMA e di NIT vengono definiti una sola volta nel program
ma chiamante mediante una frase di lettura, quelli di SX e di DX devono essere
definiti prima di ogni chiamata del sottoprogramma in quanto essi vengono mo
dificati durante l'esecuzione di RADQ. Dopo l'esecuzione del sottoprogramma
i risultati sono disponibili come valori degli argomenti attuali IND, RAD, ERR e
IT; in particolare il valore di IND viene usato dopo l'esecuzione della frase CALL
per effettuare operazioni di stampa diverse ciascuna delle quali metta in evidenza
le caratteristiche dei risultati ottenuti.
perché la lista degli argomenti attuali è composta dadue soli elementi;
perché, se Y è di tipo reale, il secondo argomento at
tuale non è dello stesso tipo del corrispondente argomento muto.
CALL PROVA (X, N)
CALL PROVA (X, Y, Z)
CALL PROVA (A, M, Y)CALL PROVA (X + Y, L, Z)CALL PROVA (X, 15, Y)CALL PROVA (X, N + l, Y)CALL PROVA (A(3), N, 8(7»CALL PROVA (R(J), L, S(N + 2»
Esempio 14.7. Si vuoI scrivere un programma per calcolare e stampare i valori
l/~ per n = 2, 3, ..., 50.
Il problema può essere risolto usando il sottoprogramma descritto nell'esempio 14.4 definito dalla frase iniziale:
dove X ed Y sono nomi di variabili reali ed N quello di una variabile intera, sono
formalmente corrette le seguenti chiamate:
Con riferimento allo stesso sottoprogramma sono invece sbagliate le seguenti
frasi CALL:
L'attivazione del sottoprogramma avviene associando, nell'ordine, gli argo
menti attuali al' a2, ... , an a quelli muti mI' m2, ... , mn ~ Per una cor~~tta associazione tra gli argomenti attuali e quelli muti occorre che ogni a. sia dello stessoI _. __ -
tipo delcorrispondente mi; inoltre, se mi è il nome di un sottoprogramma anche
ai deve esserlo mentre s-e mi è un asterisco, allora ai deve essere uno specificatoredi ritorno alternativo. In altri termini, le due liste di argomenti devono accordarsiin ordine. numero e tipo.
r Al momento dell'esecuzione di una frase CALL gli argomenti attuali corrispon-
l)denti agli argomenti muti di ingresso devono contenere le informazioni necessarie : I
I·. all'esecuzione del sottoprogramma. Dopo l'esecuzione del sottoprograrnrna, ì l! \1Il~ risultati ottenuti sono disponibili per l'unità chiamante come valori degli argo- ili, j
menti attuali corrispondenti agli argomenti muti di uscita. IiI
,I
I252 253
tipo FUNCTION nome ( )
Esempio 14.9. Sono formalmente corrette le seguenti frasi iniziali:
REAL FUNCTION MEDIA (V, N)INTEGER FUNCTION FUNZ (X, Y)FUNCTION FATT (N)FUNCTION EPSM ( )CHARACTER * 8 FUNCTION LISTA (CAR)
FUNCTIONtipodove:
• tipo è uno specificatore di tipo che può essere omesso; se presente, esso devecoincidere con uno degli specificatori INTEGER, REAL, DOUBLE PRECISION,
COMPLEX, LOGICAL oppure CHARACTER *Q;
• FUNCTION è la parola chiave che identifica la frase;• nome è un nome simbolico che costituisce il nome del sottoprogramma;
• m}' m2, .. "' mn sono gli argomenti muti che devono essere tutti distinti; ogniargomento muto può essere un nome di variabile, di variabile dimensionata o disottoprogramma.
Se il sottoprogramma FUNCTION non prevede argomenti muti, la sua primafrase deve avere la forma:
PROGRAM MAINREAL MAX,MINREAD '(3FlO.2)', X, Y, ZCALL MAXMIN (X, Y, Z, MAX,MIN)IF (MAX.NE.O.) THEN
READ '(F 10.2)', EPSCALL SOLV2(MAX, MIN, 1., EPS, Xl, X2,IND)PRiNT 1000, MAX, MIN, 1., IND
ELSEPRiNT 2000
END IFSTOP
1000 FORMAT (IX, 'COEFFICIENTI DELLA EQUAZIONE:',3(2X, E13.6)/1 IX, 'NUMERODI RADICI REALI:', 12)
2000 FORMAT (IX, 'L"EQUAZIONE E" DI PRIMOGRAOO')END
Esempio 14.8. Si vuoi scrivere un programma che permetta di stabilire il numero
di radici reali distinte dell'equazione di secondo grado ax2 + bx + l = O dove ae b sono rispettivamente il massimo ed il minimo di tre valori dati x, y e z.
Il programma richiesto può utilizzare i sottoprograrnrru MAXMIN e SOL V2
già descritti rispettivamente negli esempi 14.3 e 14.5 e può essere realizzato nel
modo seguente:
Nel programma MAIN l'esecuzione della frase
CALL MAXMIN (X, Y, Z, MAX, MIN)
permette di calcolare il massimo, MAX, ed il minimo, MIN, dei tre valori dati.
L'esecuzione del programma prosegue poi con il controllo sul valore di MAX: se
MAX è uguale a zero si esegue l'operazione di scrittura che provoca la riprodu
zione del messaggio: L'EQUAZIONE E' DI PRIMO GRADO e il programma
termina; altrimenti si legge il valore della variabile EPS e si attiva il sottoprogram
ma SOLV2 per risolvere l'equazione di secondo grado ax2 + bx + c = O con a == MAX, b = MIN, c = 1.
14.5. I sottoprogrammi FUNCTION
I sottoprogrammi di tipo FUNCfION hanno lo scopo di reé!li~~re.-JÙgOritmi
chefomiscono come risultato un !-J!1J~ valore. Per questo motivo tali sottoprogrammi sono detti anche funzioni esterne eà il loro risultato è detto valore dellafunzione.
La prima istruzione
La prima frase di un sottoprogramma di tipo FUNCfION è una istruzione non
eseguibile che ha la forma
Il valore di un sottoprogramma FUNCTION ed il suo tipo
Diversamente da quanto detto per il nome di un sottoprogramma SUBROUTlNE
il nome di una funzioneestema deve comparire come nome di variabile nelcorpo della f~;'~i~--;;e stessa almeno in una frase eseguibile che ne definisca il valo
re, Il nome di unl! f!!!1~ione esterna iQ~!Hifk.ainfaJtj li! 19ç~jQ~~ !iella quale vienememorizzato il risultato del sottoprogramma, ovvero il valore della funzione:II--tipo-dellavarlabile U-cù-i-nome~oin~id-~--;;;nil nome della funzione ovvero il
tipo del suo valore, è detto tipo della funzione, e può essere dichiarato esplicita
mente nella prima frase mediante lo specificatore di tipo in essa contenuto.La specificazione del tipo di una funzione esterna può avvenire arlC11è-òèfcorpo
del sottoprogramma mediante un'opportuna frase dichiarativa. Così, ad esempio,l'istruzione
REAL FUNCTION MEDIA (V, N)
specifica che il sottoprogramma FUNCTION fornisce un risultato reale in quanto
il nome MEDIA è di tipo reale; lo stesso effetto sarebbe stato ottenuto con lasequenza di istruzioni
FUNCTION MEDIA (V, N)REAL MEDIA
l
254255
L'unico risultato del sottoprogramma è EPSM e la lista degli argomenti è vuotaperché non ci sono dati in ingresso.
Esempio 14.12. Scrivere un sottoprogramma che, data la coppia di valori (x. v),
calcoli il valore z = ftx, y) con
altrimenti
per x~ O e y ~ O
Il seguente sottoprogramrna, di nome ZETA, risolve il problema dato; i due
argomenti muti rappresentano la coppia di dati x ed y e ZETA contiene, al termine dell'esecuzione del sottoprogramrna, il valore ft x, y).
REAL FUNCTION ZETA (X, Y)REAL X,YIF (X.LT.O..OR.Y.LT.O.) THEN
ZETA = SQRT (EXP(X» + SQRT (EXP(Y»ELSE
ZETA = SQRT(X) + SQRT(Y)END IFRETURNEND
REAL FUNCTION EPSM ( )C CALCOLO DELLA PRECISIONE DI MACCHINA
EPSM = 1.lO EPSM =0.5 • EPSM
A = 1. + EPSMIF (A.GT.1.) GO TO lOEPSM = 2.• EPSMRETURNEND
f(x, y) =
Esempio 14.13. La seguente funzione esterna calcola una stima della precisione
di macchina €m disponibile su un elaboratore quando si lavora in precisione sem
plice. L'algoritmo si basa sulla considerazione che la precisione di macchina può
essere stimata come il più piccolo numero positivo che, sommato ad l, viene«sentito» dall'elaboratore (cfr. [9], [IO]).
Si osservi che il nome FATI del sottoprogramma compare più volte nel corpo
della funzione; la prima volta il suo valore è posto uguale ad l; successivamente,
se n > l, il contenuto di FATI viene modificato all'interno del ciclo-DO in modoche, alla fine del ciclo, FATI contiene il valore n!
Esempio 14.11. Si vuoI scrivere un sottoprogramma che calcola il fattoriale n!
di un numero intero n ~ O. Ricordiamo che n! è definito da:
I sen=O
n'=/. "il i se n > O
i= l
Esempio 14.10. La sequenza di istruzioni
(l' jREAL FUNCTION VAL (A, B) iiI ll~MPLICIT DOUBLE PRECISION (R - Z) v V\.
definisce una funzione di nome VAL e di tipo reale; tutti i nomi simbolici presenti
nel corpo del sottoprogramma le cui lettere iniziali siano comprese, nell'ordina
mento alfabetico, tra R e Z sono di tipo doppia precisione ad eccezione del nomeVAL. Lo stesso effetto è ottenuto con la sequenza:
FUNCTION VAL (A, B)IMPLICIT DOUBLE PRECISION (R - Z)REAL VAL
In F66 il tipo di una funzione esterna non poteva essere specificato nel corpodel sottoprogramrna, ma solo nella prima frase.
Si osservi che il valore da calcolare cresce rapidamente al crescere di n; pertanto
è opportuno valutare n! usando l'aritmetica reale in modo da limitare la possi
bilità di overflow. Il sottoprogramma richiesto può essere quindi una funzione
esterna identificata da un nome di tipo reale quale, ad esempio, la seguente:
REAL FUNCTION FATT (N)C CALCOLA N! CON N NON NEGATIVO
FATI = 1.IF (N.GT.l) THEN
DO lO 1= 2, NlO FATI =FATI. I
ELSEEND IFRETURNEND
Si osservi che la sequenza di istruzioni
REAL FUNCTION MEDIA (V, N)REAL MEDIA
ryv è sbagliata in quanto, in una stessa unità di programma, il tipo di una variabile /0 'non può essere specificato in più istruzioni. )
Il tipo di un sottoprogramma FUNCfION può essere definito anche in modo
implicito dalla lettera iniziale del suo nome. Va notato comunque che una dichia
razione esplicita di tipo presente nella prima frase del sottoprogramma annullal'effetto di eventuali istruzioni IMPLICIT.
J,\~ ,
';1
II~,l
256 257
Riferimento ad un sottoprogramma FUNCTlON
Un sottoprogramma FUNCTION può essere chiamato da un'altra unità diprogramma utilizzando, in una qualunque espressione, un riferimento della forma
L'esecuzione di un riferimento ad una funzione esterna consiste nella attiva
zione, esecuzione e uscita dal sottoprogramma il cui nome è specificato nel riferimento. L'esecuzione del programma chiamante prosegue quindi con l'utiliz
zazione del risultato fornito dal sottoprogramma.
sen~k~O
n!
REAL A(IO, lO), COEFF
I :
altrimenti- I
r(n, k) = k! (n - k)!
Esempio 14.15. Dati due numeri interi n e k scrivere un sottoprogramma che per
metta di calcolare il valore r (n, k) definito da:
Il sottoprogramma richiesto può essere il seguente:
FUNCTION COEFF (N, K)REAL COEFF, FATTINTEGER N, KIF (N.GE.K.AND.K.GE.O) THEN
COEFF = FATT(N)/(FATT(K). FATT(N - K»ELSE
COEFF = - l.ENDIFRETURNEND
Si osservi che questo sottoprogramma richiama il sottoprogramma FATT (cfr.
esempio 14.11) per calcolare n!, k! e (n - k)!. Il sottoprogramma FATI è utiliz
zato tre volte nella stessa espressione mediante il suo nome seguito dall'indica
zione dell'argomento attuale. Ogni riferimento alla funzione esterna FATI pro
voca l'attivazione del sottoprogramma, la sua esecuzione e quindi la disponibilità
del suo risultato.
Se gli elementi aj,j di una matrice A quadrata di ordine n = lO sono definiti da
ai,j = r (i, j) i = l, ... , n, j = l, ... , n
essi possono essere calcolati usando le seguenti istruzioni:
REAL FUNCTION FUNZ (X, N)
nome ( )
Esempio 14.14. Sono formalmente corretti i riferimenti al sottoprogramma de
finito dalla frase
contenuti nelle istruzioni seguenti:
B = FUNl (X, N)R = ABS (FUNl (l, 5) + FUNl (X + Y, L»PRINT '(IX, "VALORE DELLA FUNlIONE", E13.6)', FUNZ (V, N)IF (FUNl (A, L).GT.FUNl (A + 0.5 • H, lO» THENIF (X.GT.V) V = FUNl (X - Y, I)
dove:
• nome è il nome del sottoprogramma FUNCTION;
• al' a2, •.• , an sono gli argomenti attuali ciascuno dei quali può essere unnome di variabile, un nome di variabile dimensionata, un'espressione, o il nome
di un altro sottoprogramma. La lista degli argomenti attuali deve accordarsi innumero, ordine e tipo di elementi con quella degli argomenti muti della funzione
esterna chiamata.
Si noti che un riferimento ad una funzione esterna può comparire anche nella
lista di una frase PRINT o WRITE, purché l'esecuzione del sottoprogramma nonrichieda a sua volta operazioni di uscita.
Un riferimento ad una funzione esterna che non prevede argomenti muti hala forma:
I Il tipo del nome di una funzione esterna deve risultare, in ogni unità chiamante, ~
, uguale al tipo della funzione; così, ad esempio, il sottoprogramma definito dalla 111'v
frase
DOUBLE PRECISION FUNCTION VAL (X, Y)
deve essere usato in unità di programma che contengano la frase
DO 20 J = l, ioDO 20 1= 1, lOA(I, J) =' COEFF (I, J)
20 CONTINUEDOUBLE PRECISION VAL
oppure in unità di programma in cui sono implicitamente definite di tipo doppia
precisione tutte le variabili il cui nome inizia con la lettera V.In questa sequenza di istruzioni A(l, 1) è interpretato come un nome di ele
mento di matrice mentre COEFF(l, 1) è interpretato come riferimento ad una
li
I
258
funzione esterna. Queste diverse interpretazioni derivano dalla presenza della
frase
REAL A( l O, ioi, COEFF
che definisce soltanto A come nome di matrice.
Sottoprogrammi FUNCTION di tipo carattere
Una funzione esterna è di tipo carattere se il suo nome è dichiarato, nella prima
frase o nel corpo del sottoprogramma, di tipo carattere. La lunghezza Qspecifica
ta per il nome di una funzione esterna è detta lunghezza della funzione e indica
la lunghezza del suo valore. La lunghezza di una funzione di tipo carattere può
essere espressa in uno dei modi previsti nel cap. 12 per le variabili di questo tipo
eccetto che tramite un'espressione costante intera in cui compaiono nomi simbo
lici di costante. Se la specuicazione della lunghezza non è presente, allora la fun
zione ha lunghezza l.
Esempio 14.16. Le frasi seguenti
CHARACTER • lO FUNCTJON STR (X)CHARACTER FUNCTION VOCE (Y)
sono corrette e definiscono due funzioni di tipo carattere che hanno, rispettivamente, lunghezza 10 e l. La seguente definizione della funzione carattere
CHARACTER. (LUN) FUNCTJON ERRATO (X)PARAMETER (LUN = lO)
è invece sbagliata perché la lunghezza della funzione è specificata tramite un nome
simbolico di costante. Per lo stesso motivo è sbagliata la definizione seguente:
FUNCTJON ERRATO (X)PARAMETER (LUN = JO)CHARACTER • (LUN) ERRATO
In ogni unità di programma in cui si usa una funzione esterna di tipo carattere,
il nome della funzione deve essere di tipo carattere e la sua lunghezza deve essere
uguale a quella della funzione e deve essere espressa in uno dei modi previsti nel
cap. 12 eccetto che tramite uno specificatore di lunghezza indefinita. Così, con
riferimento alle funzioni definite nell'esempio 14.16, le unità di programma chia
manti devono contenere le dichiarazioni
CHARACTER • lO STRCHARACTER VOCE
259
Osserviamo che la lunghezza di una funzione carattere può essere espressa median
te uno specificatore di lunghezza indefinita (*); in questo caso la lunghezza effet
tiva del risultato viene stabilita al momento della chiamata e viene posta uguale al
la lunghezza che il nome della funzione ha nell'unità di programma chiamante.
Esempio 14.17. Supponiamo che la funzione
CHARACTER • (.) FUNCTJON NOME (C)
sia utilizzata da due unità di programma Pl e P2 contenenti, rispettivamente,le dichiarazioni:
CHARACTER.25 NOMECHARACTER • lO NOME
Allora la funzione NOME fornisce un risultato di lunghezza 25 ogni volta cheviene utilizzata da P I mentre fornisce un risultato di lunghezza lO quando vieneutilizzata da P2.
14.6. Le funzioni definite da una frase
In ogni unità di programma si possono definire ed usare delle funzioni definite da una frase ovvero funzioni che, come dice il loro nome, sono definite da unaunica istruzione non eseguibile della forma:
dove:
• nome è il nome simbolico della funzione; il tipo di nome è il tipo della funzione;
• m)' m2, ... , mn sono gli argomenti muti che devono essere nomi distinti divariabile;
• e è un'espressione FORTRAN che può contenere, oltre agli argomenti muti
anche costanti, nomi simbolici di costante, nomi di variabile o di elementi di varia
bile dimensionata che compaiono nella stessa unità di programma. Questa espres
sione può anche contenere riferimenti a funzioni intrinseche o a funzioni esternee riferimenti ad altre funzioni definite da un'istruzione.
La frase che definisce una funzione deve precedere tutte le frasi eseguibili e se
guire tutte le frasi dichiarative presenti nell'unità di programma in cui essa com
pare. Inoltre una funzione definita da una frase deve essere preceduta da tutte le
altre funzioni definite da una frase da essa eventualmente utilizzate.
L'espressione che compare nella frase di definizione di una funzione di tipo
numerico (intero, reale, doppia precisione o complesso) può avere tipo diverso
260
dalla funzione, ma non può essere un'espressione logica o carattere; inoltre essanon può essere di tipo complesso se la funzione è di tipo doppia precisione eviceversa.
Esempio J4. J8. Sono sin tatticamente corrette le seguenti frasi di definizione difunzioni:
TRASL(X) = (- 2./(A - B». X + (A + B)/(A - B)F(X, Y) = SQRT(X •• 2 + y •• 2)
La frase:
STATUS(A, B, C) =ABS(A - B).LT.EPS.OR.C.GT.O.
è corretta solo se è preceduta dalla specificazione
LOGICAL STATUS
Una funzione definita da un 'istruzione può essere usat~ soll1ll1.liL4a/l'unit~
dip!ç}g[!!!!U!1fl in cui essa è.detìnit.a..L'utilizzazione di una funzione definita dauna frase avviene mediante un riferimento della forma:
/ nome (al' a2 , .... , an
),dove:
• nome è il nome della funzione;
• al' a2, •.•, an sono gli argomenti attuali ciascuno dei quali può essere unaespressione; la lista degli argomenti attuali deve accordarsi in numero, ordine etipo con quella degli argomenti muti.
L'esecuzione del riferimento avviene nel modo seguente: gli argomenti attualivengono associati a quelli muti e viene quindi calcolato il valore dell'espressione
che compare nella frase di definizione della funzione usando, in corrispondenza
degli argomenti muti, i valori degli argomenti attuali. Il valore dell'espressione,
eventualmente convertito al tipo della funzione secondo le regole dell'assegnazione, costituisce il risultato della funzione.
Esempio J4. J9. Consideriamo il seguente programma:
PROGRAM TABF(X) = X .. 3 - SIN (X •• 2)READ -. XO, H, NDO lO l =0, NX = XO + l. HPRINT '(IX, /IX =/1, EI3.6, IX, /lF(X) =/1, EI3.6)', X, F(X)
lO CONTINUESTOPEND
261
Lo scopo del programma è quello di scrivere i valori della funzione
f(x) = x3 - sen(x2 )
nei punti Xi = Xo + ih, con i = O, ... , n supponendo noti xo' h, n.
Nell'istruzione che definisce la funzione di nome F, l'unico argomento muto
è X. Si osservi che non c'è nessun conflitto né ambiguità sul ruolo del nome X
nel programma TAB anche se esso viene usato in altre istruzioni. Infatti al mo
mento della definizione di F, X rappresenta l'argomento muto, mentre dentro al
ciclo-DO esso è il nome della variabile che contiene il valore di Xi' Al momento
dell'attivazione di F, ovvero nella frase di scrittura, X è l'argomento attuale.
Osserviamo che lo stesso risultato del programma TAB può essere ottenuto
con il programma seguente, costituito dal programma principale TAB2 e dalla
funzione esterna F
PROGRAM TAB2READ -. XO, H, NDO lO I =0, NXT = XO + I. HPRINT '(IX, "X = ".E13.6, IX, "F(X) = ",EI3.6)', XT, F(XT)
io CONTINUESTOPEND
FUNCTION F(X)F = X •• 3 - SIN (X •• 2)RETURNEND
14.7. Le funzioni intrinseche
Come è stato sottolineato anche all'inizio di questo capitolo, le funzioni in
trinseche non sono altro che particolari sottoprogrammi che ogni sistema mette
a disposizione dell'utente. Nel cap. 6 si sono descritte alcune funzioni di uso
estremamente comune nelle applicazioni, ma in F77 sono previste molte altre
funzioni il cui significato è descritto in questo paragrafo. Ricordiamo che per
utilizzare correttamente qualunque funzione intrinseca si devono seguire le re
gole seguenti:• il numero di argomenti attuali deve coincidere con il numero di argomenti
specificato per la funzione;
• il tipo degli argomenti attuali deve essere uno dei tipi previsti per gli argomenti
della funzione;• se gli argomenti attuali sono più di uno, essi devono essere tutti dello stesso
tipo.
Ricordiamo anche che quando una funzione intrinseca può essere usata con ar-
!\ ,! .
262
Le funzioni di conversione numenca
Le funzioni che consentono di passare da una rappresentazione interna di un
dato numerico ad un'altra sono dette funzioni di conversione numer!ca._l.r- loro
caratteristiche sono riassunte in fig. 14.7 insieme a quelle di alcune funzioni
intrinseche da esse derivate e di altre destinate al trattamento dei numeri com
pIessi: per ognuna di queste funzioni si riportano in figura il numero di argomenti,
il nome generico e/o i nomi specifici, il tipo di argomenti e il tipo del risultato.
I simboli I, R, Dp, C indicano rispettivamente il tipo intero, reale, doppia preci
sione e complesso.
gomenti di tipo diverso, il tipo del risultato è determinato da quello degli argomenti
attuali, Così, ad esempio, la funzione intrinseca ABS può operare su un argomen
to di tipo intero, reale, doppia precisione oppure complesso. Nei primi tre casi
la funzione ABS fornisce il valore assoluto della quantità specificata quale argo
mento attuale ed il suo risultato è dello stesso tipo dell'argomento attuale; nel
l'ultimo caso, ovvero se l'argomento attuale è di tipo complesso, la funzione ABS
dà come risultato un valore reale che è il modulo dell'argomento. Con un unico
nome, ABS, è pertanto possibile indicare operazioni diverse in base al tipo del
l'argomento usato. La caratteristica di indicare con lo st~sso ~~~e di funzione(nome generico) operazioni diverse è comune a molte funzioni intriJ1sec~e:
L'utilizzazione del nome generico permette quindi di selezionare, mediante il
tipo degli argomenti, le operazioni che devono essere eseguite per ottenere un
I risultato coerente con i dati forniti alla funzione. Questa flessibilità delle funZiO~i.i
fhI:! intrinseche rispetto al tipo dei loro argomenti, deriva dal fatto che ciascun nome! ~t1I ~\ generico indica una famiglia di funzioni ciascuna delle quali opera su un deter~
minato tipo di argomenti per fornire uno specifico risultato. Il tipo degli argmenti attuali che, in un riferimento alla funzione, accompagnano il nome generico
determina quale sottoprogramma della famiglia deve essere effettivamente utiliz
zato e determina quindi il risultato della funzione. Nella maggior parte dei casi,
ogni sottoprogramma della famiglia identificata da ù----nnome -generico di funzione-pUò--~s~e~~-utilizzatoanche--mediatrt; un ~~o no~e spectfico,In ~ocaso gli
argomenti attuali devono essere d~i -tipop~vistoper quèIp;rticolare sottopro
gramma. Riprendendo l'esempio della funzione ABS essa indica una famiglia di
quattro sottoprogrammi le cui caratteristiche possono essere così riassunte:
263
Figura 14.7. Funzioni di conversione numerica.
Descrizione della funzione numero nome nome tipo tipo
argomenti generico specifico argomenti risultato
Conversione al tipo intero l lNT - I I
con troncamento INT,IFIX R I
(cfr.Oss.14.1) IDINT Dp I
- C I
Conversione al tipo reale l REAL REAL, FLOAT I R
(cfr. Oss. 14.2) - R R
SNGL Dp R- C R
Conversione al tipo doppia l DBLE - I Dp
precisione (cfr. Osso 14.3) - R Dp
- Dp Dp
- C Dp
Conversione al tipo 102 CMPLX - I C
complesso - R C
(cfr. Oss. 14.4) - Dp C- C C
Parte immaginaria di un l - AIMAG C R
numero complesso Dp
Complesso coniugato l - CONJG C CDp
Conversione al tipo intero l NINT NINT R I
con arrotondamento IDNINT Dp I
(cfr. Oss. 14.5)
Troncamento di un numero l AINT AINT R Rreale (cfr. Osso 14.6) DlNT Dp R
Arrotondamento di un l ANINT ANINT R Rnumero reale (cfr.Oss. 14.7) DNINT Dp Dp
1IIII
Tipo del risultato
Intero
Reale
Doppia precisione
Reale
Tipo dell'argomento
Intero
Reale
Doppia precisione
Complesso
Nome specifico
IABS
ABS
DABS
CABS
264 265
Osservazione 14.6. La funzione AINT è definita da:
te immaginaria uguale a REAL(~). Il valore di CMPLX (X, Y) è quindi il nu
mero complesso con parte reale X e parte immaginaria Y, mentre il valore di
CMPLX (X + 3., 2.) è il numero complesso che ha parte reale uguale al valore
dell'espressione X + 3. e parte immaginaria uguale a 2.
Osservazione 14.5. La funzione NINT converte un dato reale o doppia precisione al tipo intero. Questa funzjone differisce da INT in gU~!!!Qla J:onvefSiGRe-.
avviene per arrotondamento e Eon per troncamento: più precisamente si ha
NINT(a) = INT (a + 0.5) se a;;;:' ONINT(a) = INT (a - 0.5) se a < O.
Osservazioni sulle funzioni di conversione numerica
Osservazione 14.1. La funzione INT effettua la conversione al tipo intero di un
dato numerico, mediante troncamento.
Per a di tipo intero, INT(a) è uguale ad a.
Per a di tipo reale o doppia precisione, si distinguono due casi: se Ia I< l, allora lNT (a) = O; altrimenti il valore di INT (a) è un intero il cui segno coincide
con quello di a e il cui valore assoluto è il più grande intero che non supera Ia I.Così. ad esempio, INT (3.7) e INT (- 3.7) valgono rispettivamente 3 e - 3.
Per a di tipo complesso, il valore INT(a) è ottenuto applicando la regola prece
dente alla parte reale di a.
Si osservi che non sono previsti nomi specifici per questa funzione quando gli
argomenti sono di tipo intero o complesso e che i nomi specifici IFIX e IDINT
sono stati mantenuti in F77 per compatibilità con il precedente standard. AINT(a) = REAL (lNT(a» se
AINT(a) = DBLE (lNT(a» se
a è di tipo reale
a è di tipo doppia precisione
Le funzioni matematiche
In fig. 14.8 sono riassunte le caratteristiche delle funzioni intrinseche previste
in F77 per la realizzazione di funzioni matematiche quali la radice quadrata, l'e
sponenziale, il logaritmo, ecc. Le notazioni usate in fig. 14.8 sono le stesse già
usate in fig. 14.7.Per molte funzioni intrinseche di questa classe sono previste alcune restrizioni
sui valori degli argomenti in quanto il dominio delle corrispondenti funzioni ma
tematiche è un sottoinsieme dell'insieme dei numeri reali o dei numeri com
plessi. Tali restrizioni sono in generale diverse per argomenti reali e doppia precisione o per argomenti complessi; in ogni caso esse restano valide sia quando ci si
riferisce ad una funzione intrinseca con un nome specifico sia quando si usa il
nome generico.
Osservazione 14.2. La funzione REAL effettua la conversione al tipo reale di un
dato numerico.
Per a di tipo reale, REAL(a) è uguale ad a.
Per a di tipo intero o doppia precisione, REAL(a) fornisce la rappresentazione
interna del valore di a in floating-point in precisione semplice.
Per a di tipo complesso, REAL(a) è la parte reale di a.
Si osservi che non sono previsti nomi specifici per questa funzione quando gli ar
gomenti sono di tipo reale e complesso, e che i nomi specifici FLOAT e SNGL
sono stati mantenuti in F77 per compatibilità con il precedente standard.
Osservazione 14.3. La funzione DBLE effettua la conversione al tipo doppia
precisione di un dato numerico.
Per a di tipo doppia precisione, DBLE(a) = a.Per a di tipo intero o reale, DBLE(a) fornisce la rappresentazione interna del
valore di a in doppia precisione.
Per a di tipo complesso, DBLE(a) è la rappresentazione in doppia precisione del
la parte reale di a.
Osservazione 14.7. La funzione ANINT è definita da:
ANINT(a) = REAL (NINT(a» se
ANINT(a) = DBLE (NINT(a» se
a è di tipo realea è di tipo doppia precisione
Osservazione 14.4. La funzione CMPLX può avere uno o due argomenti. Se l'ar
gomento è uno solo, questo può essere di tipo intero, reale, doppia precisione o
complesso, mentre se gli argomenti sono due essi non possono essere di tipo
complesso.
CMPLX(a) è uguale ad a se a è complesso; altrimenti CMPLX(a) è il numero
complesso con parte reale uguale a REAL(a) e parte immaginaria uguale a zero.
CMPLX (al' a2) è il numero complesso con parte reale uguale a REAL(al) e par-
Osservazioni alla figura 14.8
Osservazione 14.8. Il valore dell'argomento di SQRT e DSQRT deve essere mag
giore o uguale di zero, mentre quello dell'argomento di CSQRT può essere un qua
lunque numero complesso. Indicando con Q' + i (3 il valore dell'argomento e con
'Y + i<5 il risultato di CSQRT, si ha: 'Y = 6 = O se Q' = (3 = O; altrimenti 'Y + i<5 è
quella radice di Q' + i(3 per cui è 'Y;;;:' Oe, se 'Y = O, è 6 ;;;:. O.
266
Descrizione della funzione Numero di Nome Nomi I Tipo di Tipo delargomenti generico specifici argomenti risultato
Valore assoluto o modulo I ABS IABS I IABS R R
DABS Dp DpCABS C C
Radicc quadrata I SQRT SQRT R R(cfr. 055. 14.8) DSQRT Dp Dp
eSQRT C C
Esponenziale I EXP EXP R RDEXP Dp DpCEXP C C
Logaritmo naturale I LOG ALOG R R(cfr. Osso 14.9) DLOG Dp Dp
CLOG C C
Logaritmo in base dieci I LOGIO ALOGIO R R(cfr. 055. 14.9) DLOGIO Dp Dp
Seno (cfr. 055. 14.10) I SIN SIN R RDSIN Dp DpCSIN C C
Coseno (cfr. 055. 14.10) I eos eos R RDCOS Dp Dpecos C C
Tangente (cfr. Osso 14.10) I TAN TAN R RDTAN Dp Dp
Arcoseno (cfr. 055. 14.11) I ASIN ASIN R RDASIN Dp Dp
Arcocoseno I AeOS ACOS R R(cfr. Oss.14.11) DACOS Dp Dp
Arcotangente con un I ATAN ATAN R R
argomento (cfr. 055.14.12) DATAN Dp Dp
Arcotangente con due 2 ATAN2 ATAN2 R Rargomenti (cfr. Osso 14.13) DATAN2 Dp Dp
Seno iperbolico I SINH SINH R RDSINH Dp Dp
Coseno iperbolico 1 COSH eosli R RDeOSII Dp Dp
Tangente iperbolica 1 TANH TANH R RDTANH Dp Dp
Figura 14.8. Funzioni intrinseche matematiche.
267
Osservazione 14.9. Il valore dell'argomento di ALOG, DLOG, ALOGIO e DLOGIOdeve essere maggiore di zero, mentre quello dell'argomento di CLOG deve es
sere diverso da zero. Indicando con a + il3 il valore dell'argomento e con "y + icS
il risultato di CLOG, si ha che "y + icS è il valore principale dellogarit~odi a + i/3,per il quale è - 1r < cS ~ 1re cS = 1rsoltanto se a < O e 13 = o.
Osservazione 14.10. Le funzioni SIN, COS, TAN e DSIN, DCOS, DTAN calcola
no seno, coseno e tangente di un angolo espresso in radianti.
Osservazione 14.11. Il valore assoluto dell'argomento di ACOS, DACOS, ASIN
e DASIN deve essere minore o uguale di l.
Osservazione 14.12. Il valore di ATAN(a), per a di tipo reale o doppia precisione,
è l'arcotangente di a se Ia I~ a, dove a è una quantità positiva dipendente dalla
particolare realizzazione della funzione ATAN. Se a < - a, allora il valore di
ATAN(a) è - 1r/2, mentre se a> a il valore di ATAN(a) è 1r/2.
Osservazione 14.13. Legata al calcolo dell'arcotangente è anche la funzione
ATAN2 che prevede due argomenti, di tipo reale o doppia precisione, almeno uno
dei quali diverso da zero. Infatti il risultato r di ATAN2 (al' a2) è così definito:
_ se al> O e a2
=1= O, allora r è tale che tg(r) = al/a2 e 0< r < 1r
- se al = O e a2> O, allora r = O
- se al = O e a2 < O, allora r = 1r_ se al < O e a
2=1= O, allora r è tale che tg(r) = al/a 2 e - 1r< r < O
_ se a2
= O allora r può valere 1r/2 o - 1r/2 a seconda della particolare realiz-
zazione della funzione.
Le funzioni intrinseche per la manipolazione dei caratteri
Per la manipolazione dei caratteri sono previste in F77 le funzioni intrinseche
LGE, LGT, LLE, LLT, INDEX, ICHAR e CHAR il cui significato è stato spiegato
nel cap. 12 e la funzione intrinseca LEN che permette di calcolare la lunghezza di
un dato di tipo carattere il cui utilizzo verrà esemplificato nel cap. 15. Per como
dità riportiamo nella fig. 14.9 le caratteristiche di queste funzioni; per ognuna di
esse la figura comprende una breve descrizione del significato, il numero di argo
menti, il nome specifico (non esistono nomi generici per queste funzioni) e iltipo degli argomenti e del risultato (Cr sta per «carattere», L sta per «logico» e l
sta per «intero»).
Il
r1I
'1' l,l,Il!'
Figun 14.10. Altre funzioni intrinseche.
269
SIGN (l., a) = l. se a> O
SIGN (l., a) = - 1. se a < O
l'JI\
I
,I) "
. I·l
se a l * Oe a2 ;;. Ose al * O e a2 < Ose al = O
SIGN (al; a2) = Iali
SIGN (al' a2) =-I aliSIGN (al' a2) = O
Si osservi che le funzioni SIGN, ISIGN e DSIGN in F66 erano definite nel modo
sopra indicato per a2 * O, ma non erano definite per a2 = O.Dalla definizione segue che
Numero Nome Nomi Tipo di Tipo delDescrizione della funzione di argo- generico specifici argomenti risultato
menti
Resto della divisione intera 2 MOD MOD l l(cfr. Oss. 14.14) AMOD R R
DMOD Dp Dp
Trasferimento di segno 2 SIGN ISIGN I 1(cfr. Osso 14.15) SIGN R R
DSIGN Dp Dp
Differenza positiva 2 D1M 101M l I(cfr. Osso 14.16) D1M R R
DDlM Dp Dp
Prodotto in doppia precisione 2 ~ DPROD R Dp(cfr. Osso 14.17)
Massimo fra più argomenti con risultato ;;;.2 MAX MAXO I Idello stesso tipo degli argomenti AMAXI R R(cfr. Osso 14.18) DMAXI Dp Dp
Massimo fra più argomenti con risultato ;;;.2 AMAXO I Rdi tipo diverso (cfr. Oss. 14.18) MAXI R I
Minimo fra più argomenti con risultato ;;;.2 MIN MINO l 1dello stesso tipo degli argomenti AMINI R R(cfr. Osso 14.(8) DMINI Dp Dp
Minimo fra più argomenti con risultato ;;;.2 AMINO I Rdi tipo diverso (cfr. Osso 14.18) MINI R I
Altre funzioni intrinseche
In fig. 14.10 si descrivono le caratteristiche delle rimanenti funzioni intrinse
che previste in F77, che in generale prevedono argomenti di tipo intero, reale e
doppia precisione e danno un risultato dello stesso tipo degli argomenti.
Figun 14.9. Funzioni intrinseche per la manipolazione dei caratteri,
Osservazioni sulla fig. 14.10
Osservazione 14.14. La funzione MOD prevede due argomenti, il secondo dei
quali deve essere diverso da zero, e calcola il resto della divisione effettuata in
aritmetica intera fra il primo ed il secondo argomento. In altri termini essa è
definita da
Descrizione della funzione Numero di Nome Tipo degli Tipo delargomenti specifico argomenti risultato
Relazione di ~ nel codice ASCII 2 LGE Cr L
Relazione di > nel codice ASCII 2 LGT Cr L
Relazione di '" nel codice ASCII 2 LLE Cr L
Relazione di < nel codice ASCII 2 LLT Cr L
Posizione della prima occorrenza di una 2 INDEX Cr Istringa a2 in una stringa al
Posizione dell'argomento nel sistema di l ICHAR Cr Icodifica usato dall'elaboratore
Carattere che occupa, nel sistema dicodifica usato dall'elaboratore, la posìzio- l CHAR I Crne espressa dall'argomento.
Lunghezza dell'argomento l LEN Cr I
268
Osservazione 14.15. La funzione SIGN prevede due argomenti e il risultato è
defini to da:
ovvero segue che per a * O SIGN (1., a) dà come risultato il valore assunto inx = a dalla funzione sgn(x) definita da:
SIGN (0.5, a) - SIGN (0.5, - a)
D'altra parte sgn(a) può essere calcolato, per qualunque valore di a, utiliz
zando la funzione SIGN nel modo seguente
270
lsgn(x) = O
-l
x>O
x=O
x<O
271
Esercizi
14.1 Individuare gli errori presenti nelle seguenti istruzioni:
SUBROUTINE NEW (A, B, 0.5))
SUBROUTINE STAMPA (I, J, A(I, 1)
SUBROUTINE COPIA (X, Y, F(X»
REAL FUNCTION MEDIA (M, M +1, V)
FUNCTION INDICE (CAR (I : I))
COMPLEX FUNCTION MODULO
Osservazione 14.16. La funzione DIM prevede due argomenti, ed è definita da
DIM (al' a2) = al - a2DIM (al' a2) = O
Osservazione 14.17. La funzione DPROD calcola il prodotto in doppia precisione
fra due argomenti reali. Così, se A e B sono variabili reali e D e DD sono variabili
in doppia precisione, l'istruzione
D = DPROD (A, B)
è equivalente alla coppia di istruzioni
DD=A
D = DD * B.
Osservazione 14.18. Le funzioni MAX e MIN determinano, rispettivamente, il
massimo e il minimo fra due o più argomenti; il risultato è dello stesso tipo degli
argomenti. Esistono inoltre le funzioni AMAXO e MAXI (AMINO e MINI) che
calcolano il massimo (minimo) fra più argomenti e convertono poi il risultato a un
tipo diverso da quello degli argomenti. Queste funzioni sono state mantenute in
F77 per compatibilità con lo standard precedente F66, ma saranno probabil
mente eliminate nella prossima versione del FORTRAN. Del resto è possibile si
mulare queste funzioni intrinseche tramite la MAX e la MIN e le funzioni di con
versione numerica; così, ad esempio se al' a2, ... , an sono di tipo intero, si ha
AMAXO (al' a2, .•• , an ) = REAL (MAX (al' a2, , an))
AMINO (al' a2, .. "' an ) = REAL (MIN (a" a2, , an))
mentre se a" a2, ... , an sono di tipo reale si ha
MAXI (a" a2, ... , an ) = INT (MAX (al' a2, ... , an))
MINI (a" a2, · · ", an ) = INT (MIN (al' a2, · · · , an))
Come si è già accennato nel cap. 6, in F66 non esistevano nomi generici per
le funzioni intrinseche, ma soltanto nomi specifici e inoltre molte funzioni pre
viste in F77 non erano previste in F66 (cfr. appendice A2).
14.2 E' dato il sottoprogramma seguente
SUBROUTINE ESERC (M, MI, ALFA, BETA)
INTEGER M, MI
REAL ALFA, BETA
END
Supponendo che A e B siano variabili reali e M e N variabili intere, indicare
quali tra le istruzioni CALL seguenti sono formalmente corrette e quali
non lo sono.
CALL ESERC (M, N, A, B) .: I
CALL ESERC (M, B, A) ,1(
CALL ESERC (4, N, A, B) s {CALL ESERC (N, M, 0.5, 0.5) :. I
CALL ESERC (A, B, M, N) II (l
CALL ESERC (M, N, S, B) " (.;
14.3 E' dato un sottoprogramma FUNCTION di tipo reale e di nome EFFE
che prevede, quali argomenti muti, due variabili reali. Individuare gli even
tuali errori formali nelle seguenti istruzioni che utilizzano EFFE, suppo
nendo che A e B siano variabili reali e K sia una variabile intera:
IF (EFFE (A, B).GT.EFFE (O., O.)) A = EFFE (A, B)
X = EFFE (A, B) - EFFE (B, A)
B = EFFE (O; 0.5) ti )
READ *, A, B, EFFE (A, B)
A = ABS (EFFE()9, B» rI ()
EFFE (A, B) = EFFE (A, B) - 1.
PRINT *, EFFE (A) ì10
14.4 Trasformare in un sottoprogramma il programma dell'Esempio 10.9, giu
stificando la scelta fra un sottoprogramma FUNCTION o un sottopro
gramma SUBROUTINE.
(soluzioni: l e - 3)
x2-0.2001104x+0.l001l0?=0
x2 _ 2 10- 3 x + 10- 6 = O
x2 - 6 x + 34 = O
x2 - 105 x + l = O
I J
272
14.5 Scrivere un sottoprogramma che, dato un vettore reale di 100 elementi,fornisca come risultato la media aritmetica dei valori dei suoi elementi.Giustificare la scelta fra un sottoprogramma FUNCfl0N e un sottoprogramma SUBROUTINE.
14.6 Scrivere un sottoprogramma che utilizza il sottoprogramma SOLV2 delloesempio 14.5 per calcolare le soluzioni reali o complesse delle seguentiequazioni:x:l + 2x - 3 = O
(soluzioni: 1000e 1001)
(soluzioni: 10- 3 e 10- 3)
(soluzioni: 3 + Si, 3 - Si)
(soluzioni calcolate con Il cifre:0.99999999990 105 e0.1000000000 l 10- 4)
Eseguire i calcoli suddetti utilizzando i seguenti valori di e: €M' lO €M'
100 €M' dove €M è la precisione di macchina che può essere calcolata conil sottoprogramma EPSM dell'esempio 14.13.
14.7 Spiegare il significato assunto dal sottoprogramma EPSM dell'esempio14.13 se si sostituisce la frase iniziale con le frasi
DOUBLE PRECISION FUNCfION EPSM ( )DOUBLE PRECISION A
14.8 Scrivere un sottoprogramma di tipo SUBROUTINE che, assegnato un
vettore X reale di 100 elementi e un intero N, con O< N < 100, permettadi localizzare, se esiste, il primo elemento di X diverso da zero a partire daX(N) e fornisca come risultato la posizione, LOC, di tale elemento e il suovalore, V. Il sottoprogramma deve inoltre segnalare con un opportuno valore di LOC il caso in cui tutti gli elementi di X a partire da X(N) siano uguali
a zero.
14.9 Scrivere un sottoprogramma che risolva il problema del precedente esercizio, ma fornisca in uscita soltanto il valore di LOC.
14.10 Scrivere un sottoprogramma FUNCfION che permetta di calcolare, assegnato il numero complesso z, il valore complesso w(z), dove
w(z) = Iz I+ (l + 3i) z
273
Scrivere inoltre un programma che utilizza il precedente sottoprogrammaper calcolare e stampare i valori di w(z) per i seguenti valori di z: 2 - 3i,S. 8 + 102 i, - 5i.
14.11 Scrivere un sottoprogramma che, assegnata una stringa X di 60 caratteri,fornisca in uscita una stringa W costituita dai caratteri di X diversi dal carattere blank, e il numero di questi caratteri. Scrivere inoltre un programmache utilizzi il sottoprogramma suddetto avendo come dato la stringa:
'MATTEOvHAvFATTOvUNAvCORSAvEDvORAvHA vlLv RESPIROvAFFANNOSOvvvv'
14.12 Individuare quali fra le seguenti frasi che definiscono una funzione sono
sintatticamente corrette:
F(A, B, C) = (A + B + C)/3.F(A, B, C, 3) = (A + B + C)/3
F = (A + B + C)/3
14.13 Individuare gli errori contenuti nei seguenti riferimenti a funzioni intrinseche, supponendo che R, l, C siano variabili di tipo reale, intero e com
plesso rispettivamente.
SQRT(I)
ABS (CMPLX(R, I»CMPLX (AIMAG(R»NINT (C)
MOD (R, NINT(R»EXP (lNT(R».
14.14 Scrivere un sottoprogramma che consenta di calcolare il prodotto scalarefra due vettori reali di N elementi, con N ~ SO, e che utilizzi la funzioneintrinseca DPROD per eseguire i prodotti in doppia precisione (cfr. esempio Il.22).
J
15Argomenti mutied argomenti attuali
15.1. Associazione tra argomenti muti ed argomenti attuali
L'attivazione di un sottoprogramma e la sua esecuzione presuppongono uno
scambio di informazioni tra unità di programma chiamante e sottoprogramma.
Questo scambio può avvenire attraverso la lista degli argomenti muti in quanto
ad essa è associata quella degli argomenti attuali in modo tale che, durante l'esecuzione del sottoprogramma, ogni riferimento ad un argomento muto. è di fatto,
un riferimento al corrispondente argomento attuale. Al momento della chiamata
di un sottoprogramma viene infatti trasmesso per ciascun argomento muto l'indi
rizzo del corrispondente argomento attuale e diventano pertanto direttamente
utilizzabili dal sottoprogramma gli indirizzi delle locazioni in cui si trovano me-
1morizzati i valori degli argomenti attuali. Gli argomenti muti di Wl sottopro- .gramma sono quindi completamente definiti soltanto al momento della attivazione del sottoprogramma quando ognuno di essi identifica la stessa locazione dimemoria del corrispondente argomento attuale. La corretta esecuzione di un sot- .
toprogramma è pertanto subordinata ad una corretta corrispondenza tra gli argo-menti muti e quelli attuali; eventuali errori non sono generalmente segnalati dalsistema e si manifestano in fase di esecuzione con risultati del tutto inattendibili
che provocano talvolta l'interruzione del programma. Si osservi che gli errori
commessi nella associazione degli argomenti non possono essere segnalati durantela compilazione in quanto ogni unità di programma è compilata in modo autono
mo e separatamente da tutte le altre.
15.2. Le variabili non dimensionate come argomenti muti
Quando un argomento muto è il nome di una variabile non dimensionata adesso può corrispondere, nella lista degli argomenti attuali, una variabile, un elemento di variabile dimensionata, una costante oppure. più in generale, un'espressione. In ogni caso l'argomento attuale deve essere dello stesso tipo di quellomuto.
277276
Esempio 15.1. Sia ESEMP un sottoprogramma definito da:
SUBROUTINE ESEMP (ARG, N)
con ARG ed N nomi di variabile rispettivamente di tipo reale ed intero. Suppo
nendo che nell'unità di programma chiamante X identifichi una variabile reale,
Y un vettore reale, L una variabile intera ed M una matrice intera, il sottopro
gramma ESEMP è correttamente utilizzato dalle frasi:
CALL ESEMP(X, L)CALL ESEMP(X, M(I, 2))CALL ESEMP(Y(3), L + lO)CALL ESEMP(L • Y(2)/X, 12)
mentre sono sbagliate le seguenti istruzioni:
ANG = TETA(Y) + TETA (0.5 * H)
richiede due esecuzioni del sottoprogramma TETA: la prima avviene associando
all'argomento muto X quello attuale Y, la seconda associando ad X la locazione
che contiene il valore dell'espressione 0.5 • H. Anche la frase
ANG = TETA (TETA(Y) + H)
~imPlica due esecuzioni del sottoprogramma TETA: la prima avviene usando l'in
! diriz~o di Y e l~ seconda usando l'.indiriz~o della locazione nella quale è memoriz
zato 11 valore di TETA (Y) + H. SI osservi che questo modo di utilizzare un sotto
programma di tipo FUNCfION non è ricorsivo.
Esempio 15.3. Sia SOMMA un sottoprogramma definito da:
SUBROUTINE SOMMA (A, B, C)
lI
, iI '
f
CALL ESEMP(L, X)CALL ESEMP(X, 1.05)CALL ESEMP(Y(3), X + lO)CALL ESEMP(M(l, 2). L, 12)
con A, B e C nomi di variabili reali. Supponendo che A e B siano argomenti
di ingresso e che C sia di uscita, l'esecuzione della frase
CALL SOMMA (X, X, Y)
permette di associare A e B alla stessa locazione X e C alla locazione Y; sarebbe
invece sbagliato scrivere
15.3. Le variabili dimensionate come argomenti muti
Quando un argomento muto è il nome di una variabile dimensionata, ad esso
deve corrispondere come argomento attuale un nome di variabile dimensionata
oppure un nome di elemento di variabile dimensionata. Ricordiamo che all'in
terno del sottoprogramma il nome dell'argomento muto deve comparire in una
opportuna frase di specificazione che ha come unico effetto quello di indicare al
compilatore che l'argomento è una variabile dimensionata; 'inoltre i nomi degli
elementi dell'argomento muto devono essere utilizzati nel sottoprogramma coe
rentemente con la specificazione fatta. Anche in questo caso, l'esecuzione del
sottoprogramma avviene utilizzando per l'argomento muto le locazioni di memo
ria riservate all'argomento attuale dall'unità di programma chiamante, in quanto
l'associazione tra l'argomento muto e quello attuale avviene mediante l'indirizzo
dell'argomento attuale. Più precisamente, l'indirizzo del primo elemento dell'ar-
;I . CALL SOMMA (X, Y, Xl Il/i1111 quanto alla stessa locazione farebbero riferimento sia un argomento di ingresso
che quello di uscita.
Esempio 15.2. Sia TETA un sottoprogramma definito dalla frase:
dove X indica un nome di variabile reale. L'esecuzione dell'istruzione
REAL FUNCfION TETA (X)
Va sottolineato che ad ogni argomento muto di uscita deve corrispondere
come argomento attuale una variabile oppure un elemento di variabile dimensio- Inata. In altri termini una costante o una espressione non devono essere usate i A
come argomento attuale in corrispondenza di un argomento muto il cui valore v
sia definito oppure modificato nel corpo del sottoprogramma. Infatti, se l'argo
mento attuale è una costante, qualunque modificazione del corrispondente argo
mento muto provoca un cambiamento del valore della costante che invece deve
rimanere inalterato durante tutta l'esecuzione del programma. Il divieto di utiliz
zare un'espressione in corrispondenza di un argomento muto di uscita deriva, in
vece, dal fatto che l'associazione tra l'espressione ed il corrispondente argomento
muto avviene mediante l'indirizzo della locazione nella quale, al momento della
chiamata del sottoprogramma, è memorizzato il valore dell'espressione. Questo
indirizzo viene trasmesso al sottoprogramma ma non è noto all'unità di program
ma attivante che, pertanto, non lo può utilizzare. Si osservi infine che, se due 'j',argomenti attuali coincidono. nessuno dei corrispondenti argomenti muti può ['
essere un argomento di uscita.
278
gomento muto coincide con quello del primo elemento dell'argomento attualese
questo è il nome di una variabile dimensionata; se invece il parametro attuale è un
elemento di variabile dimensionata, il suo indirizzo viene utilizzato dal sottopro
grarnma come indirizzo del primo elemento del parametro muto. In ogni caso, gli
indirizzi dei successivi elementi dell'argomento muto vengono determinati a
partire dall'indirizzo del primo elemento in base al numero di dimensioni e alle
limitazioni di ciascuna dimensione dell'argomento muto secondo le modalità
viste nel cap. II.
Esempio 15.4. Il seguente sottoprogramma, SOM, permette di sommare i quattro
elementi di un vettore V con gli elementi di posto dispari di un vettore W di am
piezza IO. Il risultato viene memorizzato nella variabile reale A.
SU8ROUTINE SOM (V, W, A)REAL V(4), W(IO)A=Q.DOlO, 1=1,4A = A + V(I)
IO CONTINUEDO 20 1=1,10,2A = A + W(I)
20 CONTINUERETURNEND
Questo sottoprogramma può essere correttamente utilizzato nel modo seguente:
REAL X(IO), Y(20)
CALL SOM (X, Y, Al)CALL SOM (X(6), Y(II), A2)CALL SOM (Y, X, A3)
Dopo l'esecuzione di queste frasi
A I contiene:
1l
279
muti V e W sono rispettivamente associati a X ed Y mediante l'indirizzo di X( I)
ed Yt l ): con l'esecuzione della seconda chiamata il primo elemento di V è associato all'elemento X(6) ed il primo elemento di W a Yf l l ): infine, l'ultima attiva
zione del sottoprogramma avviene associando V ad Y mediante l'indirizzo di Y( I)
e W ad X mediante l'indirizzo di X( I).
Si osservi che quando un argomento muto ed il corrispondente argomento
"' attuale sono nomi di variabili dimensionate, l'argomento attuale deve avere ami piezza maggiore o uguale a quella dell'argomento muto, ovvero il numero totale
degli elementi dell'argomento muto non deve superare quello del corrispondente
!argomento attuale. Quando l'argomento attuale è un elemento di variabile dimen
l' i sionata, l'ampiezza dell'argomento muto non deve superare il numero di elementi
J\ di tale variabile compresi fra l'elemento specificato come argomento attuale e
l'ultimo.
.4Esempio 15.5. Si vogliono sommare gli elementi di una matrice di 2 righe e 2
colonne con quelli di posto dispari della terza colonna di una matrice B di IOrighe e 3 colonne.
Questo problema può essere risolto utilizzando il sottoprogramrna SOM
dell'esempio 15.4 nel modo seguente:
REAL A(2, 2), 8(10,3)
CALL SOM (A, B(1,3),S)
AI momento dell'attivazione del sottoprogramma il primo elemento dell'ar
gomento muto V è associato al primo elemento della matrice A mentre il primo
elemento di W è associato al primo elemento della terza colonna di B; infine
l'argomento muto di uscita A è associato ad S. Durante l'esecuzione del sotto
programma gli elementi degli argomenti muti V e W sono associati agli elementi
dei corrispondenti argomenti attuali nel modo seguente:
X(l) + X(2) + X(3) + X(4) + Y(l) + Y(3) + Y(5) + Y(7) + Y(9)
A2 contiene:
X(6) + X(7) + X(8) + X(9) + Y(lI) + Y(l3) + Y(l5) + Y(l7) + Y(l9)
V(I)
A(I,I)
V(4)
A(2,2)
A3 contiene:
Y(l) + Y(2) + Y(3) + Y(4) + X(1) + X(3) + X(5) + X(7) + X(9)
Infatti, al momento della prima chiamata del sottoprogramma gli argomenti
W(l) W(2) W(3) W(4) W(5) W(6) W(7) W(8) W(9) W(lO)
8(l,3) 8(2,3) 8(3,3) B(4,3) 8(5,3) B(6,3) 8(7,3) 8(8,3) 8(9,3) B(IO,3)
280
Esempio 15.6. Supponiamo di utilizzare ancora il sottoprogramma SOM del
l'esempio 15.4 nel modo seguente:
REAL A(3, 3),8(3, lO)
CALL SOM(A,8(1,3),S)
In questo caso, gli elementi del parametro muto V corrispondono a quelli del
parametro attuale A nel modo seguente:
V(l) V(2) V(3) V(4)
A(l,l) A(2,1) A(3,1) A(1,2)
mentre gli elementi di W e quelli di B si corrispondono nel modo seguente:
W(1) W(2) I W(3) W(4) W(5) W(6) W(7) W(8) W(9) W(10)
8(1,3) 8(2,3) 8(3,3) 8(1,4) 8(2,4) 8(3,4) 8(1,5) 8(2,5) B(3,5) 8(1,6)
15.4. Dimensionamento variabile e dimensionamento indefinito
In un sottoprogramma è possibile specificare le dimensioni di un argomento
muto mediante una particolare forma di dichiaratore di dimensione detta dichia
ratore di dimensione variabile. Un dichiaratore di dimensione è detto dichiaratore
di dimensione variabile se contiene un'espressione intera in cui compare almeno.
un nome di variabile; questo nome di variabile deve far parte della lista degli argo
menti muti o di un blocco COMMON (cfr. cap. 16). Nel ~~g~i!(}':!I!,!jJ~edichia
rativa nella quale compare un dichiaratore di dimensione variabile verr~Q~tta fra
se di dimensionamento variabile; essa deve precedere tutte le frasi eseguibili del
corpo del sottoprogramma ma deve essere preceduta da tutte le eventuali frasi di
specificazione che interessano le variabili intere usate nei dichiara tori. Sono per
tanto esempi di corretta utilizzazione del dimensionamento variabile i seguenti:
SU8ROUTINE ESI (V, A, N)REAL V(N), A(N, N)
SUBROUTlNE ES2 (V, R, S)INTEGER R, SREAL V(R: S)
REAL FUNCTION ES3 (V, M, N)REAL V(M + N • 5)
j
281
REAL FUNCTION ES4 (V, W, A, N)DIMENSION A(N, 7), W(19, N + I), V(O : N - 3)
L'ampiezza delle dimensioni specificate con i dichiaratori di dimensione variabile è determinata al momento dell'attivazione del sottoprogramma. In questa
fase infatti viene definito il valore delle variabili intere usate nei dichiaratori e sono valutate le espressioni che compaiono nei dichiaratori stessi. Il valore dei di-
jChiaratOri di dimensione variabile resta inalterato durante tutta l'esecuzione del I
l sottoprogramma anche se il contenuto delle variabili intere usate nei dichiaratori Ltviene modificato.
Esempio 15.7. Supponiamo che
SUBROUTlNE SU81 (V, W, A, NV, NW)REAL V(NV), W(NV + NW + 2)
siano le frasi iniziali del sottoprogramma SUB 1. In esse V e W indicano due vettori reali le cui dimensioni sono specificate mediante gli argomenti muti NV edNW. Se, al momento della attivazione di SUB l, gli argomenti attuali corrispon
denti ad NV ed NW valgono entrambi 15, allora durante l'esecuzione di SUBI ilvettore V viene considerato di ampiezza 15 e W di ampiezza 32; se invece, al mo
mento della chiamata di SUB l, NV contiene il valore lO ed NW il valore - 5,
il sottoprogramma viene eseguito come se fosse stata usata la specificazione.
REAL V( lO), W(7).
Esempio 15.8. Per calcolare l'elemento massimo di un vettore X di N elementi
si può usare il seguente sottoprogramma:
REAL FUNCTION MMV(X, N)INTEGER NREAL X(N)MMV = X(l)DO 200 1 = 2, NIF (X(I).GT.MMV) MMV = X(l)
200 CONTINUERETURNEND
E' possibile utilizzare questo sottoprogramma per calcolare i massimi elementi
delle colonne di una o più matrici reali. Supponendo che A sia una matrice di l Orighe e 5 colonne e che B sia una matrice di 20 righe e 40 colonne, il seguenteprogramma permette di definire i valori dei 45 elementi di un vettore V memoriz-
,i
I11
282
zando nei primi S, gli elementi massimi di ciascuna colonna di A e, nei restanti 40,
gli elementi massimi di ogni colonna di B.
PROGRAM USOMMVREAL A(lO, 5), B(20, 40), V(45), MMVNRA = lONCA=5NRB = 20NCB =40READ -. A, BDO 20 I = I, NCAV(I) = MMV(A(l, I), NRA)
20 CONTINUEDO 30 I = I, NCBV(NCA + I) = MMV(B( l, I), NRB)
30 CONTINUEPRINT -. VSTOPEND
All'interno del primo ciclo-DO il sottoprogramma MMV viene attivato NCA
volte ed ogni attivazione avviene associando il primo elemento di una colonna di
A al primo elemento dell'argomento muto X la cui ampiezza è determinata dal
valore, lO, di NRA. All'interno del secondo ciclo-DO il sottoprogramma è invece
attivato NCB volte: ogni volta il primo elemento di una colonna di B è associato
al primo elemento dell'argomento muto X la cui ampiezza, determinata dal valore
di NRB, è uguale a 20. Si osservi che, per una corretta utilizzazione del sottopro
grarnma, è indispensabile specificare nell'unità di programma chiamante che
MMV è di tipo reale.
Esempio 15.9. Siano xl' x2' .. " xn le componenti di un vettore x; indicata conIl la quantità
Il = max I x·1 'l" i" n I
la norma euclidea di x, ~ x Ib, può essere calcolata nel modo seguente:
se Il = O
se Il =1= O
Un sottoprogramma che permette di calcolare, dati x ed n, la norma Il x 112 è
1I
283
allora il seguente:
REAL FUNCTION NORMA2 (X, N)C NORMA2 INDICA LA NORMA EUCLIDEA DEL VETTORE XC N INDICA IL NUMERO DI ELEMENTI DI X
REAL MI, X(N)C CALCOLO DEL MASSIMO FRA I VALORI ASSOLUTIC DEGLI ELEMENTI DI X
MI = ABS(X(I»DO IO 1= 2, NIF (MI.LT.ABS(X(I») MI= ABS(X(I»
IO CONTINUENORMA2 = o.IF(MI.EQ.O.) RETURNDO 20 I = l, NNORMA2 = NORMA2 + (X(I)/MI) ** 2
20 CONTINUENORMA2 = MI * SQRT (NORMA2)RETURNEND
Il sottoprogramma NORMA2 può essere utilizzato per calcolare la quantità
dove c(i) indica la i-esima colonna di una matrice A di m righe ed n colonne. Sup
ponendo m = lO ed n = S, SC può essere calcolato dal programma seguente:
PROGRAM V ALSCREAL A(lO, 5), NORMA2READ *, AM=ION=5SC =0.DO IO I = I, NSC = se + NORMA2 (A(I, I), M)
IO CONTINUEPRINT -. 'QUANTITA"VCALCOLATAv', SCSTOPEND
Questo programma deve essere notevolmente modificato se, invece della quantità sc' si vuoI calcolare
sr = t 1/r(i) 112i= 1
284
dove r(i) indica la i-esima riga della matrice A. Si considerino infatti le seguenti
istruZIOI1I, analoghe a quelle usate nel programma VALSC:
SR =0.DO lO I = l, MSR = SR + NORMA2 (A(I, l), N)
lO CONTINUE
L'esecuzione di queste istruzioni prevede che, per ogni valore di I, il primo ele
mento dell'argomento muto X abbia lo stesso indirizzo di A(l, l) e che l'ampiezzadi X sia uguale a S. Durante l'esecuzione del sottoprogramma, gli elementi di Xsono quindi associati ad A(l, l) e alle quattro locazioni di memoria ad esso con-
secutive nel modo seguente:
X(l)
A(I, l)
Pertanto, per ogni valore di i, il sottoprogramma NORMA2 fornisce la quantitài+ 4 5
(I: a~ l )1/ 2 e non quella utile per il calcolo di sr che è data da (. I: a; /1 2. Af-
j~ i J. J= l •finché il problema possa essere correttamente risolto occorre che gli elementi diciascuna riga di A vengano memorizzati, prima della chiamata del sottoprogramma, in locazioni consecutive di memoria. Per questo si utilizza un vettore, RIGA,nel quale vengono memorizzati tutti gli elementi della i-esima riga di A. Questovettore costituisce l'argomento attuale che aeve essere associato a quello mutoX per poter calcolare la norma euclidea della i-esima riga di A. Il programma può
essere allora il seguente:
PROGRAM VALSRREAL A(lO, 5), NORMA2,RIGA (5)
READ -. AM=1ON = 5SR=O.DO 20 l = l, MDO lO J = l, N
lO RIGA (1) = A(I, J)SR = SR + NORMA2 (RIGA, N)
20 CONTINUEPRINT -. 'VALOREvCALCOLATOvSR =', SRSTOPEND
285
Dimensionamento variabile per argomenti muti con due o più dimensioni
Per chiarire come deve essere usato il dimensionamento variabile per argomenti
muti con due o più dimensioni, consideriamo il seguente esempio.
Esempio 15.10. Sia MATRIX un sottoprogramma definito dalla frase iniziale:
SUBROUTINE MATRIX (A, N, M. B)
dove A, N ed M sono gli argomenti di ingresso e B è quello di uscita e, inoltre, A
è una matrice specificata da
REAL A(N, M)
Sia PROGI un programma che utilizza MATRIX nel modo seguente:
PROGRAM PROGIREAL X(3, 4), Y(2, 3)READ *, X, YNR=3NC =4CALL MATRIX (X, NR, NC,BI)CALL MATRIX (Y, NR - l, NC - l, B2)
Al momento della prima attivazione del sottoprogramma, l'argomento muto
A è associato a quello attuale X mediante l'indirizzo di X( l, l) e inoltre N è associato ad NR, M a NC e B a Bl. Per effetto della prima frase CALL si crea quin
di tra gli elementi di A e quelli di X una associazione per la quale ogni elemen
to A(I, 1) nel sottoprogramma corrisponde all'elemento X(l, 1) del program
ma principale per ogni valore di I, l ~ 1 ~ 3, ed ogni valore di J, l ~ J ~ 4. Al
momento della seconda chiamata, l'argomento muto A è associato ad Y mediante
l'indirizzo di Y( l, l), la variabile N è associata alla locazione che contiene il
valore dell'espressione NR - l, la variabile M è associata alla locazione che con
tiene il valore di NC - 1 e B è associata a B2. L'esecuzione della seconda frase
CALL stabilisce pertanto che ogni elemento A(I, J) corrisponde a Y(l, J) per ogni
I compreso fra l e 2 e J compreso fra 1 e 3.Esaminiamo ora come avviene la associazione tra argomenti muti ed argomenti
attuali supponendo di usare il sottoprogramma MATRIX con la seguente unità
di programma chiamante:
'Ii,
, IlI l
I
·ìlI
286
PROGRAM PROG2REAL X(3,4)READ -, XNR=3NC =4CALL MATRIX (X, NR, NC, BI)CALL MATRIX (X, NC, NR, B2)CALL MATRIX (X, NR - l, NC + 2, B3)CALL MATRIX (X, NR, NR, B4)
La corrispondenza che si crea tra gli elementi dell'argomento muto A e quelli
dell'argomento attuale X con l'esecuzione delle quattro frasi CALL presenti in
PROG2 è la seguente:
TI
287
gli elementi dell'argomento muto coincidono con quelli che individuano gli elementi dell'argomento attuale soltanto se il numero di righe dell'argomento mutocoincide con il numero di righe specificato per l'argomento attuale nell'unità di
programma chiamante.
Esempio 15.11. II seguente sottoprogramma DEFMAT permette di risolvere il
seguente problema: dato n, determinare gli elementi h(n) di una matrice quadrata1.1
Hn di ordine n definiti da
n se i = j
h~nJ = n/(j + 1) se i > j i, j = 1,2, ... , nr.j
(i - 1)/0 - 1) se i <j
Prima CALL:
Seconda CALL:
xn.n X(2,l) X(3,1) X(l,2) X(2,2) X(3,2) X(l,3) X(2,3) X(3,3) X(l,4) X(2,4) X(3,4)
A(l,l) A(2,l) A(3,l) A(I,2) -\(2,2) A(3,2) A(l,3) A(2,3) A(3,3) A(l,4) A(2,4) A(3,4)
xci, l) X(2,l) X(3,l) X(I,2) X(2,2) X(3,2) X(l,3) X(2,3) X(3,3) X(1,4) X(2,4) lX(3,4)
A(1,I) A(2,1) A(3,l) A(4,1) A(l,2) A(2,2) A(3,2) A(4,2) A(l,3) A(2,3) A(3,3) IA(4,3)
SUBROUTINE DEFMAT (H, NR, N)REAL H(NR, N)DO 20 1= 1, NDO 20 J = I, N1F (I.EQ.J) THEN
H(I, J) = NELSE IF(I.GT.J) THEN
H(I, J) = N/(1 + 1.)ELSE
H(I, J) =(1- 1.)/(1 - 1.)ENDIF
20 CONTINUERETURNEND
II significato degli argomenti muti di DEFMAT è il seguente: H è una matrice
reale che contiene, al termine dell'esecuzione del sottoprogramma, la matrice Hn ;
NR ed N sono argomenti di ingresso, il primo dei quali serve per specificare ilnumero di righe di H nel descrittore di dimensione variabile e il secondo rappre
senta l'ordine n della matrice Hn di cui si devono definire gli elementi.
Consideriamo ora il seguente programma principale, ATTIVA, nel quale il sottoprogramma DEFMAT viene utilizzato 5 volte durante l'esecuzione del ciclo-DO
per calcolare successivamente le matrici Hn, con n = 2, 4,6, 8, IO e memorizzarle
nelle stesse locazioni di memoria riservate alla matrice di ordine maggiore. Si noti
che, durante ogni esecuzione di DEFMAT, gli indici che individuano gli elementi
dell'argomento muto H e gli elementi dell'argomento attuale ad esso associato
concidono. Questa coincidenza di indici è dovuta al fatto che ad ogni attivazione
il valore dell'argomento attuale NR è uguale al numero di righe specificato per
l'argomento attuale H nel programma ATTIVA.
X(3,4)
A(2,6)
X(1.1)
X(1,1) X(2,1) X(3,l) X(l,2) X(2,2) X(3,2) X(l,3)
A(l,l) A(2.l) A(l,2) -\(2,2) A(l,3) A(2,3) A(1,4)
A(1,1)
L'esempio precedente mette in evidenza che, quando il numero di righe di una
matrice usata come argomento muto non coincide con quello specificato per il
corrispondente argomento attuale, alcuni elementi delI'argomento muto risul
tano associati ad elementi dell'argomento attuale individuati da indici diversi.
In altri termini, quando si utilizza un sottoprogramma che prevede tra gli argomenti muti una matrice, si deve tener presente che gli indici che individuano
Terza CALL:
Quarta CALL:
288
PROGRAM ATTIVAREAL H(lO, lO)NR= lODO lO N = 2, 10,2PRINT., 'ORDINE DELLA MATRICE N =', NCALL DEFMAT (H, NR, N)DO lO I = l, NWRITE (.,1000) (H(l, J), J = l, N)
lO CONTINUESTOP
1000 FORMAT (lO (IX, E12.S»END
Le osservazioni fatte per le matrici valgono anche quando un argomento muto
ha più di due dimensioni. Infatti, se m è il numero di dimensioni, gli indici che in
dividuano gli elementi dell'argomento muto coincidono con quelli degli elementi
dell'argomento attuale associato, soltanto se al momento dell'attivazione i valori
dei dichiaratori delle prime (m - 1) dimensioni dell'argomento muto coincidono
con quelli fissati per l'argomento attuale nell'unità di programma chiamante.
In questo caso l'ampiezza dell'ultima dimensione dell'argomento muto non deve
superare quella dell'ultima dimensione dell'argomento attuale.Il dimensionamento vanabile era previsto anche in F66 ma erano ammessi
come dichiaratori di dimensione variabile soltanto nomi di variabili intere facenti
parte della lista degli argomenti muti o di un blocco COMMON.
Dimensionamento indefinito
In F77 è prevista una ulteriore forma particolare di dichiaratore di dimensione
per un argomento muto, detta dichiaratore di dimensione indefinita. Si dice che
un argomento muto ha dimensionamento indefinito se l'ultimo dichiaratore di
dimensione è un asterisco. Sono esempi di uso del dimensionamento indefinito
le frasi
REAL X(*), B(10, *), A(M, *)DIMENSION Y(- 5 : N, *), Z(N + M, L, *)
Se un argomento muto ha dimensionamento indefinito, la sua ampiezza non
viene calcolata al momento dell'attivazione del sottoprogramma la cui esecuzione
avviene quindi ignorando l'ampiezza dell'argomento muto; per q~~s!O!1l()!!VQ, un
parametro muto che ha dimensionamento indefinito non può essere usato nel cor
po del sottoprogramma in frasi la cui esecuzione richiede la conoscenza esplicita
della sua ampiezza. Così, per esempio, la frase:
PRINT *, A
289
non può essere usata in un sottoprogramma se A è una matrice che compare nella
lista degli argomenti muti ed ha dimensionamento indefinito.
Il dimensionamento indefinito non è previsto in F66.
15.5. Argomenti muti di tipo carattere
Se un argomento muto di un sottoprogramma è di tipo carattere, il suo tipo e
la sua lunghezza devono essere opportunamente specificati all'interno del sottoprogramma.
Se l'argomento muto è una variabile carattere, il corrispondente argomento at
tuale può essere una costante, una variabile, una sottostringa, un elemento di
variabile dimensionata, oppure un'espressione carattere. In ogni caso la lunghezzadell'argomento muto non deve superare quella dell'argomento attuale. Se la lun
ghezza ~ dell'argomento muto è uguale a quella dell'argomento attuale, al momen
to dell'attivazione del sottoprogramma l'argomento muto è associato alla stringaidentificata dall'argomento attuale mediante !'indirizzo dell'unità di memoria
in cui è memorizzato il primo carattere dell'argomento attuale. Se invece la lun
ghezza ~ dell'argomento muto è inferiore a quella dell'argomento attuale, l'argo
mento muto è associato alla sottostringa costituita dai primi ~ caratteri dell'argomento attuale.
Esempio 15.12. Indicate con LI ed L2 due lettere dell'alfabeto, il sottoprogram
ma seguente permette di stabilire se la stringa di lunghezza 8 rappresentata dal
l'argomento muto DATO inizia con LI e termina con L2. Il sottoprogramma
infatti determina il valore di una variabile logica, IND, il cui valore è «vero» sol
tanto se DATO inizia con LI e termina con L2. Nel caso in cui IND sia «falso»,
il sottoprogramma memorizza il carattere iniziale e quello finale di DATO in LIed L2 rispettivamente.
SUBROUTlNE INFIN (DATO, IND, LI, L2)LOGICAL INDCHARACTER DATO. 8, LI • l, L2 • lN=8IF (DATO (I: l ).EQ.Ll.AND.DATO (N: N).EQ.L2) THEN
IND= .TRUE.ELSE
IND = .FALSE.LI = DATO (l:l)L2 = DATO (N:N)
ENDIFRETURNEND
II >
III
II"
292
Sarebbe invece sbagliata l'istruzione
CALL INFIN (X//A, IND, IN, FIN)
in quanto in essa figura come argomento attuale un'espressione carattere nella
quale un operando, X, è un argomento muto di lunghezza indefinita.
Se un argomento muto è una variabile dimensionata di tipo carattere, l'argo
mento attuale ad esso corrispondente deve essere di tipo carattere e può essere
il nome di una variabile dimensionata, di un elemento di variabile dimensionata,
di una sottostringa di un elemento di variabile dimensionata. In ogni caso, l'asso
ciazione tra l'argomento muto e quello attuale viene fatta mediante l'indirizzo
dell'unità di memoria in cui è memorizzato il primo carattere dell'argomento
attuale. Si osservi che quando un argomento è una variabile dimensionata carat
tere esso individua unità di memoria consecutive in quanto l'ultimo carattere di
ogni elemento è immediatamente seguito dal primo carattere dell'elemento suc
cessivo. Il numero di unità di memoria carattere individuate da un argomento
costituisce la sua lunghezza complessiva. In particolare, se un argomento attualeè il nome di un elemento o di una sottostringa di un elemento di una variabile
dimensionata, la sua lunghezza complessiva è costituita dal numero di caratteri
compresi tra il primo carattere dell'elemento o della sottostringa specificati e
l'ultimo carattere dell'ultimo elemento.La lunghezza dei singoli elementi di un argomento muto di tipo carattere può
differire da quella degli elementi dell'argomento attuale ma la sua lunghezza com
plessiva, determinata in base alla specificazione presente nel sottoprogramma, non
deve superare quella dell'argomento attuale.
15.6. I nomi di sottoprogrammi come argomenti muti. Le frasi EXTERNAL e
INTRINSIC
Un argomento muto di un sottoprogramma può essere il nome di unaltr() sot
toprogramma e, in questo caso, il corrispondente argomento attuale deve essere,
a sua volta, il nome di un sottoprogramma. Così, per esempio, se il nome, NOME,
di un sottoprogramma fa parte della lista degli argomenti muti di un altro sotto
programma, CHIAMA, ogni riferimento a NOME all'interno di CHIAMA equivale
ad un riferimento al sottoprogramma il cui nome è specificato come argomento
attuale in corrispondenza di NOME. Per poter realizzare l'associazione tra il
nome del sottoprogramma presente nella lista degli argomenti muti e quello spe
cificato come argomento attuale, quest'ultimo deve apparire in una opportuna
frase dichiarativa nell'unità di programma chiamante.Per semplicità di esposizione nel seguito useremo il termine sottoprogramma
293
esterno per indicare un sottoprogramma SUBROUTINE oppure FUNCTION.
La frase EXTERNAL
L'istruzione dichiarativa EXTERNAL permette di individuare, in una lista di
argomenti, i nomi di sottoprogrammi esterni; essa ha la forma seguente:
EXTERNA L lista
dove:• EXTERNAL è la parola chiave che identifica la frase;
• lista è una lista di uno o più nomi di sottoprogrammi di tipo SUBROUTINE,FUNCTION, BLOCK DATA. Se la lista è costituita da più nomi, essi sono separa
ti da virgole.Ogni nome di sottoprogramma che compare nella lista di una frase EXTERNAL
può essere usato come argomento attuale nella stessa unità di programma in
cui compare la frase EXTERNAL. D'altra parte, se un nome di sottoprogramma
esterno fa parte di una lista di argomenti attuali esso deve comparire. nella stessa
unità di programma, in una frase EXTERNAL. Per esempio la frase:
EXTERNAL FUNZ, F
indica che i nomi FUNZ ed F sono nomi di sottoprogrammi esterni e che essi
possono essere usati come argomenti attuali nell'unità di programma che contiene
questa frase.Si osservi che~Uquando un nome simbolico compare in un'istruzione EXTERNAL
esso è interpretato come il nome di un sottoprogramma esterno; in particola
re, se la lista di una frase EXTERNAL comprende il nome di una funzione in
trinseca, quel nome individua un sottoprogramma esterno diverso dalla funzio
ne intrinseca. Così la specificazione
EXTERNAL SQRT
serve per indicare che nell'unità di programma in cui essa compare SQRT è il no
me di un sottoprogramma esterno diverso dalla omonima funzione intrinseca. E'
evidente che in questa unità di programma non è possibile utilizzare la funzione
intrinseca SQRT perché ogni riferimento ad SQRT viene interpretato come un ri
ferimento al sottoprogramma esterno e non alla funzione intrinseca.Si noti che in F66 il nome di una funzione intrinseca non poteva essere usato
come nome di un sottoprogramma esterno e la sua presenza nella lista di una frase
EXTERNAL serviva soltanto a specificare che esso poteva essere usato come
argomento attuale nella stessa unità di programma.
Esempio 15.15. Sia f(x) una funzione reale definita per x ~ xo' con f(xo) * 0,
e sia € > O una quantità assegnata. Supponendo noti i valori xo' h, n si considera-
, :\I I
I ·1,~
. I
290
Questo sottoprogramma può essere usato per determinare il primo e l'ultimocarattere di stringhe di lunghezza 8, come nel seguente esempio:
CHARACTER IN, FIN, VI .8,LOGICAL INDIN='G'FIN = 'E'VI = 'GIUSEPPE'CALL INFIN (VI, IND, IN, FIN)
L'argomento muto DATO corrisponde all'argomento attuale VI, ed entrambisono di tipo carattere e lunghezza 8; pertanto, durante l'esecuzione del sottoprogramma il valore di DATO è 'GIUSEPPE'. Gli argomenti attuali IND, IN, FINcorrispondono rispettivamente agli argomenti muti IND, LI ed L2. Siccome ivalori in ingresso di LI ed L2 sono 'G' ed 'E', dopo l'esecuzione del sottoprograrn
ma IND contiene il valore .TRUE. e i contenuti di IN e FIN sono immutati.Sia ora V2 una variabile carattere di lunghezza 14 contenente la stringa di caratteri 'MARIA v GELTRUDE' . Se IN e FIN valgono 'G' ed 'E' rispettivamente,
dopo l'esecuzione della frase
CALL INFIN (V2(7:), IND, IN, FIN)
i valori di IND, IN e FIN sono, nell'ordine, .TRUE., 'G' ed 'E', mentre essi di
ventano .FALSE., 'M'ed 'E' se viene eseguita la frase
CALL INFIN (V2, IND, IN, FIN)
Infatti nel primo caso l'argomento muto DATO viene associato alla sottostringaV2(7:) che vale 'GELTRUDE', mentre nel secondo caso esso viene associatoalla sottostringa costituita dai primi 8 caratteri di V2, ovvero a 'MARIA vGE'.
Si osservi che non sarebbe corretto utilizzare il sottoprogramma INFIN associando a DATO una stringa di lunghezza inferiore a 8. Per esempio è sbagliata lafrase:
CALL INFIN ('FRANCO', IND, IN, FIN)
in quanto l'argomento attuale corrispondente a DATO è la stringa 'FRANCO' dilunghezza 6.
L'esempio precedente mette in evidenza che l'obbligo di specificare nel corpodel sottoprogramma la lunghezza degli argomenti di tipo carattere può limitare lepossibilità di utilizzazione del sottoprogramma stesso. Per questo è prevista lapossibilità di definire la lunghezza di un argomento muto di tipo carattere mediante lo specificatore di lunghezza indefinita (.); in questo modo la lunghezza
291
di un argomento muto viene definita soltanto al momento della chiamata delsottoprogramma quando viene posta uguale a quella dell'argomento attualecorrispondente.
Esempio 15.13. Supponiamo di modificare il sottoprogramma INFIN dell'esempio 15.12 nel modo seguente:
SUBROUTINE INFIN (DATO, IND, LI, L2)LOGICAL INDCHARACTER DATO. (.), LI • l, L2. lN = LEN (DATO)IF (DATO(l: l ).EQ.Ll.AND.DATO (N:N).EQ.L2) THEN
IND= .TRUE.ELSE
IND = .FALSE.LI =DATO(l:l)L2 = DATO (N:N)
ENDIFRETURNEND
In questo caso il sottoprogramma può essere usato per determinare il primo e
l'ultimo carattere di qualsiasi stringa; infatti all'argomento muto DATO viene assegnata, al momento della attivazione del sottoprogramma, la stessa lunghezzadell'argomento attuale corrispondente. Si osservi che in questa seconda versionedel sottoprogramma INFIN è necessario usare la funzione intrinseca LEN percalcolare la lunghezza di DATO.
Si osservi che un argomento muto di tipo carattere la CUI lunghezza sia stataspecificata con (.) può comparire come operando in una operazione di concatenazione soltanto in una frase di assegnazione.
Esempio 15.14. E' corretta la seguente sequenza di istruzioni, dove INFIN è
il sottoprogramma dell'esempio precedente:
SUBROUTINE CONCAT (X, Y, A, IN, FIN)CHARACTER. (.) X, Y, A. 3, IN • l, FIN. lLOGICAL INDY = X/lACALL INFIN (Y, IND, IN, FIN)
I
I294
no i punti xi = Xo + ih con O~ i ~ n. Si vuole scrivere un sottoprogramrna, dinome SGN, che permetta di individuare, se esiste, il più piccolo valore di j, con
0< j ~ n, tale che f(xj) f(x j_ 1) < O e, in caso affermativo. fornisca in uscita i va
lori di j, Xj_ l' Xr Inoltre il sottoprogramma deve interrompersi se, per un valore
di i > O. si ha If(x) I~ € e in questo caso deve dare come risultati il valore j = - i
e il valore di Xi' Infine, se nessuna delle precedenti condizioni è verificata, il sot
toprogramma deve fornire in uscita il valore j = n + I e i valori di Xo e xn '
Stabiliamo di utilizzare le variabili XO, H, N ed EPS come argomenti muti di
ingresso contenenti rispettivamente xo' h, n ed e, e la variabile JCS come argo
mento di uscita che contiene il valore di j. Inoltre stabiliamo che l'argomento
muto XO contenga in uscita il valore di Xi se il sottoprogramma termina perché
If(x) I~ e, mentre usiamo gli argomenti XO e XN per memorizzare i valori di
xj_ 1 e Xj oppure Xo e xn negli altri due casi. Il sottoprogramma SGN, di tipo
SUBROUTINE, deve richiamare un altro sottoprogramma di nome FUNZ, con il
quale si calcola f(x) per un valore di x assegnato. Il sottoprogramma FUNZ può
essere di tipo FUNCTION e prevedere come unico argomento muto una variabile
reale che in ingresso contiene il valore di x; in uscita FUNZ fornisce il valore f(x).
II sottoprogramma SGN può essere quindi così formalizzato:
SUBROUTINE SGN (XO, XN, H, N, EPS, JCS)F = FUNZ(XO)SEGNO = SIGN (I., F)DOlO J=I,NXN = XO+ J. HF = FUNZ (XN)IF (ABS(F).LE.EPS) THEN
XO =XNJCS =-JRETURN
ELSE IF (SIGN(l., F).NE.SEGNO) THENXO =XN - HJCS = JRETURN
ELSEENDFI
IO CONTINUEJCS = JEND
La prima istruzione del sottoprogramma FUNZ richiamato da SGN deve essere
REAL FUNCfION FUNZ (X)
1295
e il suo corpo può descrivere qualunque funzione reale f(x) definita per x ;;;;. xo'D'altra parte, il sottoprogramma SGN non può essere usato se il sottoprogramma
che calcola f(x) ha un nome diverso da FUNZ. In particolare esso non può essere
utilizzato nella stessa unità di programma per esaminare il comportamento di
due o più funzioni distinte che sono ovviamente realizzate da sottoprogrammi
FUNCfION con nomi distinti. Perché ciò sia possibile, occorre modificare la pri
ma istruzione di SGN inserendo il nome FUNZ nella lista degli argomenti muti;
in altri termini si deve usare un sottoprogramma, SGN I, il cui corpo è identico a
quello di SGN e la cui prima frase è
SUBROUTINE SGNI (XO. XN, H, N, EPS, JCS, FUNZ)
Durante l'esecuzione di SGN l ogni riferimento a FUNZ provoca l'attivazione del
sottoprogramma il cui nome è specificato nella lista degli argomenti attuali.
Così, se FCf, F e VALF sono i nomi di tre sottoprogrammi FUNCfION di tipo
reale e con un solo argomento di ingresso di tipo reale, è corretto il seguente uso
diSGNI:
EXTERNAL FCT,F,VALF
CALL SGNI (XO, XN, H, N, EPS, JCS, FCT)
CALL SGNI (XO, XN, H, N, EPS, JCS, F)
CALL SGNI (XO, XN, H, N, EPS, JCS, VALF)
L'istruzione EXTERNAL è indispensabile per poter usare FCf, F e VALF
come argomenti attuali corrispondenti a FUNZ.
Esempio 15.16. Sia F una funzione che associa ad ogni elemento x di IRn un vet
tore y = F(x) di IRn . Assegnati due vettori u e v appartenenti ad IRn ed un intero
Q> O, sia xk ' con O~ k ~ Q, il vettore definito da:
Si vuoI scrivere un sottoprogramma che, supponendo noti u, v, ~, n ed F permet
ta di determinare tra i vettori xk ' O~ k ~ Q, quel vettore xj tale che
Il F(xj)llz = min I] F(xk ) 112' O~ k ~ Q}
Il sottoprogramma richiesto, che chiameremo MF2, può essere scritto tenendo
presente il seguente algoritmo:
296
l. Dati: u, v, ~, n
2. Poni xj = v3. Calcola y = F(xj )
4. Calcola m = l y lil5. Ripeti per k = 1,2, ... ,~:
5. 1. poni (\ = k/ ~
5.2. poni xk = Q:kU + (I - Q:k) v
5.3. calcola y = F(xk
)
5.4. calcola mk = Il y Ib5.5. se mk ~ m allora: esegui 5.6
altrimenti: poni m = mkponi xj = xkesegui 5.6
5.6. continua il procedimento ripetitivo.
6. Risultati: m, xj
7. Stop
Si osservi che le istruzioni 4. e 5.4 di Questo algoritmo possono essere realiz
zate tramite il sottoprogramma NORMA2 dell'esempio 15.9 la cui frase iniziale
è la seguente:
REAL FUNCfION NORMA2(X, N)
Inoltre, l'esecuzione delle istruzioni 3. e 5.3 prevede l'utilizzazione di un altro
sottoprogramma che identitichiamo con il nome FX e che, dato il vettore x, per
metta di calcolare il vettore y = F(x). Il sottoprogramma FX deve essere di tipo
SUBROUTINE e deve prevedere due argomenti di tipo reale: quello di ingresso,
X, contenente il vettore x e quello di uscita, Y, contenente il vettore y = F(x).
Pertanto la frase iniziale di FX è
SUBROUTINE FX(X, Y)
mentre il corpo di FX è costituito da tutte le istruzioni che permettono di definire
i singoli elementi di Y.
Per definire la frase iniziale del sottoprogramma MF2 si noti che esso deve esse
re una SUBROUTINE e che, per essere utilizzabile qualunque sia il valore di n.de
ve prevedere il dimensionamento variabile dei vettori utilizzati. La lista degli ar
gomenti muti di MF2 deve quindi comprendere i seguenti nomi di variabile. U,
V, L, N, XJ, M, XK, Y che rappresentano, rispettivamente, u, v, ~, n, Xj' m,
xk
' y. I primi quattro nomi indicano gli argomenti di ingresso; XJ ed M sono gli
argomenti di uscita; XK ed Y sono nomi di vettori che devono comparire nella
lista degli argomenti muti in quanto utilizzati con dimensionamento variabile.
La lista degli argomenti muti può inoltre comprendere il nome FX del sottopro-
297
gramma utilizzato per calcolare Ftx); questo permette l'utilizzazione di MF2
anche nel caso in cui la funzione Ft x) sia definita da un sottoprogramma la
cui frase iniziale ha la stessa forma indicata per FX ma il cui nome è diverso da
FX. Tenendo presente le osservazioni fatte, il sottoprogramma MF2 può essere
costituito dalle seguenti istruzioni:
SUBROUTINE MF2 (U, V, L, N, XJ, M, XK, Y, FX)REAL U(N), V(N), XJ(N), XK(N), Y(N)REAL M, NORMA2, MKOOlOl=I,N
lO XJ(I) = V(I)CALL FX(XJ, Y)M = NORMA2 (Y, N)RL=LDO 40 K = l, LALFAK = K/RLDO 20 I = l, N
20 XK(I) = ALFAK • U(I) + (I. - ALFAK) • V(I)CALL FX (XK, Y)MK = NORMA2 (Y, N)IF (MK.GE.M) GO TO 40M=MKDO 30 I = l,N
30 XJ(I) = XK(I)40 CONTINUE
RETURNEND
Supponendo che F(x) sia la funzione
essa può essere descritta mediante il seguente sottoprogramma:
SUBROUTINE FUNZ (X, Y)REAL X(3), Y(3)Y(I) = (X(2) •• 2 + 2.• EXP(- X(3»)/12.Y(2) = (I. - X(I) + SIN (X(3»)/6.Y(3) = (X(1) •• 2 + X(2) •• 2 + X(3) •• 2)/6.RETURNEND
Assegnati i vettori u = (I, l, I)T e v = (- l, - l, - 1)1 e fìssato P.e 15,ilsotto
programma MF2 può essere utilizzato nel modo seguente:
~i
f.·i
,~
i
l
298
REAL Y(3), Y(3), XK(3), D(3), XJ(3)EXTERNAL FUNZREAD * D, YN=3L= 15CALL MF2 (D, Y, L, N, XJ, EMME, XK, Y, FDNZ)WRITE («, 1(0)(XJ(I), I = I, N)
100 FORMAT (IX, 'vETTORE DI MINIMA NORMA'/3 (IX, E13.6»WRITE (*,200) EMME
200 FO RMAT (I X, 'vALORE DELLA NORMA', 2X, E13.6)STOPEND
AI momento dell'attivazione di MF2 viene effettuata l'associazione tra gli
argomenti muti e quel1i attuali e, in particolare viene associato ad FX il nome del
sottoprogramma FUNZ. Il programma è pertanto costituito dal programma prin
cipale e dai sottoprogrammi MF2, NORMA2 e FUNZ.
La frase INTRINSIC
Un nome simbolico in una lista di argomenti attuali viene interpretato come
nome specifico di una funzione intrinseca se nel1a stessa unità di programma esso
compare nella lista di una istruzione INTRINSIC. Questa frase dichiarativa, che
non esisteva in F66, ha la forma:
INTRINSIC lista
dove:
• INTRINSIC è la parola chiave che identifica la frase;
• lista è una lista di nomi specifici di funzioni intrinseche separati da virgole.
Si osservi che soltanto i nomi specifici delle funzioni intrinseche, e non i nomigenerici, possono essere usati come argomenti attuali e che, se in un'unità di pro
gramma viene usato come argomento attuale il nome specifico di una funzione
intrinseca, questo nome deve comparire nella stessa unità di programma in una
frase INTRINSIC. Inoltre, non devono essere usati come argomenti attuali i nomi
di funzioni intrinseche che permettono conversioni di tipo (lNT, IFIX, IDINT,
FLOAT, SNGL, REAL, DBLE, CMPLX, ICHAR, CHAR), che stabiliscono l'or
dinamento dei caratteri (LGE, LGT, LLE, LLT), che determinano il massimo o
il minimo di un insieme di valori numerici (MAX, MAXO, AMAX I, DMAX I,
AMAXO, MAX I, MIN, MINO, AMIN I, DMIN I, AMINO, MIN I).
Esempio 15.17. Fissati i valori di xo' n, h ed € si vuole studiare il comporta
mento della funzione sin(x) nei punti Xi = Xo + ih, O :ç i :ç n, nel senso indi
cato nell'esempio 15. I 5. Si può allora utilizzare il sottoprogramma SGN I facendo
corrispondere al1'argomento muto FUNZ il nome specifico SIN della funzione
T299
intrinseca che calcola sin(x) e che prevede un argomento di tipo reale. In questo
caso il nome SIN deve comparire in una istruzione INTRINSIC nel1a unità di pro
gramma chiamante; in altri termini, questa deve contenere le due frasi seguenti:
INTRINSIC SIN
CALL SGNI (XO, XN, H, N. EPS, JCS, SIN)
In questo modo, durante l'esecuzione di SGN I, ogni riferimento a FUNZ è, di
fatto, un riferimento al1a funzione intrinseca SIN.
15.7. Asterischi come argomenti muti
L'asterisco può far parte del1a lista degli argomenti muti di un sottoprogramma
SUBROUTINE; ad esso deve corrispondere, come argomento attuale, uno specifi
catare di ritorno alternativo che ha la forma:
* sdove• s è l'etichetta di una frase eseguibile appartenente al1a stessa unità di pro
gramma in cui compare lo specificatore.
La denominazione «specificatore di ritorno alternativo» con la quale si indica
un argomento attuale del tipo * s è legata all'effetto di una particolare forma
della frase RETURN che può essere utilizzata al1'interno di un sottoprogramma
SUBROUTINE. Questa forma è la seguente:
RETURN
dove:
• RETURN è la parola chiave che identifica la frase;
• t è un espressione intera il cui valore è utilizzato per individuare !'istruzione
del programma chiamante che deve essere eseguita al1a fine del1'esecuzione del sot
toprogramma. Più dettagliatamente, supponiamo che il sottoprogramma abbia n
argomenti muti del1a forma asterisco e che contenga l'istruzione
RETURN
AI momento dell'esecuzione di questa frase viene valutato il valore k dell'espres
sione intera t. Se k < I oppure k > n la frase RETURN t ha lo stesso effetto
della frase RETURN. Se invece I :ç k :ç n, il valore k identifica il k-esimo asteri
sco tra gli n presenti nella lista degli argomenti muti e il control1o dell'esecuzione
è rimandato all'istruzione della unità di programma chiamante la cui etichetta èassociata, mediante uno specificatore di ritorno alternativo, al k-esimo asterisco.
300
Esempio J5. J8. Indicate con LI ed L2 due lettere dell'alfabeto, si vuole scrivere
un sottoprogramma che permetta di stabilire se la stringa rappresentata dall'ar
gomento muto VOCE inizia con LI e termina con L2, inizia con LI ma non ter
mina con L2, termina con L2 ma non inizia con LI, non inizia con LI e non
termina con L2. In ogni caso, il sottoprogramma deve fornire il carattere iniziale e
finale di VOCE memorizzandoli in LI ed L2 rispettivamente. Tenendo conto che
il sottoprogramma deve selezionare uno fra quattro possibili casi, esso può preve
dere fra gli argomenti muti tre asterischi ed essere realizzato nel modo seguente:
301
Se, durante l'esecuzione di RlTALT, viene eseguita l'istruzione RETURN,
allora l'esecuzione del programma principale prosegue con l'istruzione seguente
la CALL; essa prosegue invece con l'istruzione di etichetta IO, 20 o 30 rispetti
vamente se in RlTALT viene eseguita l'istruzione RETURN l, RETURN 2 oRETURN 3.
La possibilità di usare i ritorni alternativi non esisteva in F66.
Esercizi
15.1 Scrivere un sottoprogramma mediante il quale, dati un vettore A di compo
nenti al' ... , an e un vettore B di componenti bI' ..., bn
_ l' si costruisce
il termine dn di una successione {di' i = O, ... , n }definita da
do = l
dI = al
di = ai di_ l - br_ l di_ 2' per i = 2,3, ..., n
e si verifica se dn è maggiore di 1/3. Scrivere inoltre un programma che
utilizza questo sottoprogramma con i seguenti dati:
SUBROUTINE RIT ALT (VOCE, LI, L2, *, -. *)CHARACTER VOCE * (*), LI, L2N = LEN(VOCE)IF (VOCE(l: 1).EQ.L1.AND.VOCE(N:N).EQ.L2) RETURNIF (VOCE(l:l).EQ.L1) THEN
L2 = VOCE (N:N)RETURN l
ELSE IF (VOCE(N:N).EQ.L2) THENLI = VOCE(l:l)RETURN 2
ELSELI = VOCE (l : l)L2 =VOCE (N:N)
ENDIFRETURN 3END
Un programma principale che utilizza RITALT è il seguente:
n=6 A = (1,2, lO, - 5, 6, 8) B = (6, 7, 8, 9, lO).
Scrivere un nrogramrna che utilizza il sottoprogramma precedente con iseguenti dati:
m
Ci,j= L ai,k bk,j peri= l, ...,nej= l, ...,~k=l
Scrivere un sottoprogramma che calcoli il prodotto C = AB, dove A è una
matrice reale di n righe ed m colonne e B è una matrice di m righe ed ~ co
lonne. Si ricorda che la matrice prodotto C ha n righe ed ~ colonne ed i
suoi elementi sono definiti da:
lO
20
30
CHARACTER * 7 NOME, IN * l, FIN * lREAD -. IN, FINPRINT *, 'CARATTERE INIZIALE DATO', INPRINT -. 'CARATTERE FINALE DATO', FINREAD *, NOMECALL RIT ALT (NOME, IN, FIN, * lO, *20, *30)PRINT -. 'NOME INIZIA CON:', IN,'E TERMINA CON:', FINSTOPPRINT -. 'L"ULTIMO CARATTERE DI NOME E":', FINSTOPPRINT -. 'IL PRIMO CARATTERE DI NOME E":', INSTOPPRiNT -. 'IL PRIMO CARATTERE DI NOME E":', INPRINT *, 'L"ULTIMO CARATTERE E":', FIN
STOPEND
15.2
(
- I
A= O
0.5
O
O
- l
3
-5
2.1
8.3 ) (O - 1.5)- ~.4 B = - ~.5 100
15.3 Scrivere un sottoprogramma mediante il quale, data una matrice reale A
di n righe ed m colonne, si determina il numero di variazioni di segno della
302 303
Scrivere infine un programma principale che, usando i due sottoprogrammi
precedenti, calcoli le variazioni di segno delle successioni {vi} associate alla
matrice MIO e alla matrice M6, La seconda matrice deve occupare le stessecelle di memoria della prima.
Scrivere un sottoprogramrna che, dato in ingresso un vettore intero di n
elementi, fornisca in uscita la posizione del massimo e del minimo elemen
to. Scrivere inoltre un programma principale che utilizzi il sottoprogramma
per localizzare il massimo e il minimo elemento dei seguenti vettori:
tuno il caso in cui tutti gli elementi vk
' ' .. , vn siano minori o uguali di m.
l Jtilizzare il sottoprogramrna con i dati seguenti:
v=(0,14,17,18,20) k=2 m=15;
v = (- S, 2, 8, 1S, 30) k = 3 m = 31.
15.7 Siano a = (al' .. " an) e b = (bI' ..., bm) due vettori i cui elementi sononumeri interi distinti ordinati in senso crescente. Usando il sottoprogramma
scritto nell'esercizio precedente scrivere un altro sottoprogramrna che per
metta di costruire un terzo vettore c = (Cl' . , ., cn+ m) tale che ogni suo
elemento sia un elemento di a o di b e, nel complesso, i suoi elementi siano
ordinati in senso crescente (per esempio, per a = (- 1,2) e b = (O, 5,7) si
ha c = (- 1, O, 2, S, 7)).
Scrivere un programma che utilizzi il sottoprogramma con i dati seguenti:
a = (15,20,100), b = (S, 6,35, SO, 5 I),
15.8 Dati due interi m ed n, sia ftx) la funzione definita nel modo seguente:
per i = 1, ... , n e j ~ i
per i = 1, .. "n e j > im(n) =
I,)
successione {vi' i = 1, ..., n}, dove vi è il massimo elemento della riga
i-esima di A. Scrivere inoltre un secondo sottoprogramma che, dato un
intero n > l, determini gli elementi m(n) di una matrice quadrata M diI,) n
ordine n definita da:
1jn + 1-1
15.4
(- l, O, 5,80) (5,8, - 4, l O) (40,50,60,70) (-3,-5,-8,-1) se x ~- 1
II programma deve usare un unico vettore di 16 componenti per memoriz
zare i quattro vettori dati e due vettori di quattro elementi per memoriz
zare le posizioni degli elementi massimi e degli elementi minimi rispettiva
mente.
f(x) = m tg (- 7rx/4)
m . n 3- jf x) - - (x - 1)n m +
se-l<x~O
se x>O
15.5 Scrivere un sottoprogramma mediante il quale, assegnato il valore x, si cal
cola il valore della funzione f(x) definita da:
dove j(x) e (x - l)~ sono date da:
se x ~ 1
se x < l.
Scrivere poi un programma principale che calcola e stampa la media arit
metica dei valori f(l/3), f(5/2), t(O), f(4/3),
15.6 Sia v un vettore intero assegnato di componenti vI' ..., vn e siano k ,
1 ~ k ~ n, ed m due interi dati. Supponendo che le componenti di v siano
ordinate in senso crescente, scrivere un sottoprogramma che fornisca la
posizione e il valore del primo fra gli elementi vk ' ... , Vn il cui valore è
maggiore di m. Inoltre il sottoprogramma deve segnalare in modo oppor-
La funzione f(x) deve essere calcolata mediante un sottoprogramma di tipoFUNCfION supponendo che per il calcolo della funzione j(x) sia disponibi
le una funzione esterna JX con le seguenti caratteristiche:
Scrivere un programma che provveda a leggere i valori di m ed n ed a me
morizzare in un vettore e quindi stampare i valori assunti da f(x) nei punti
seguenti:
1 2 4- 3" O, 3" 3"' 1, 3
4 2- 3"' - 1, -'3'
Prima frase: REAL FUNCfION JX (X, N, A)
Scopo: calcolo del valore assunto nel punto x dal polinomio esponenzialen
j(x) = ~ a ck xk=O k
per O~ x < 1/2
per 1/2 ~ x < 1
per 1 ~ x ~ 3/2
altrimenti
sin (2x - l)
f(x) = sin (2x - l) + cos (2x - 1)sin (2x - l) + cos (2x - l) - tgx
O
I
"ì'
II,l'
(
305
304
15.9 Data l'equazione x = f(x) e posto Ntx) = f(f(x)) - 2 f(x) + x, sia
Fissato un valore Xo reale, sia {x k} la successione di valori reali definiti
da
Argomenti muti:X: variabile reale contenente in ingresso il valore di x;
N: variabile intera contenente in ingresso il valore di n;A: vettore intero di N + l elementi contenente in ingresso i coefficienti
<lo' al' ... , an ·
n=4, k=2, 1=(2,3), J=(1,3)
A = (~: ~~ ~: ~: )25 26 27 28
31 32 33 34In questo caso verranno modificati gli elementi delle prime 2 righe e 2 co
lonne di A, che quindi avrà in uscita la forma seguente:
15.12 Assegnata una parola chiave costituita da Q lettere dell'alfabeto inglese,
si vuole codificare una frase data secondo il seguente sistema di codifica.
Alla parola chiave viene associato un vettore v = (VI' ..., v~) tale che v.è la posizione dell'i-esima lettera della parola chiave nell'alfabeto inglese.Così, per esempio, se la parola chiave è CHIAVE si ha v = (3, 8, 9, l,22,S).
Se il numero di caratteri della frase che si vuole codificare non è un multi
plo di Q, si aggiungono in coda alla frase un certo numero di caratteri blank
in modo da ottenere una stringa, MESS, la cui lunghezza r sia multiplo di Q.
Così, continuando il nostro esempio, se la frase da codificare è
'UN '17 BEL 'I7PANORAMA' si ha MESS = 'UN '17 BEL 'I7PANORAMA'I7'17v'.
15.11 Scrivere un programma principale atto a:l) leggere i valori degli elementi di una matrice reale A di ordine lO e
deivettori 1=(iI,i2,i))e J=(jI,j2,j3);2) se gli elementi di I e J soddisfano le ipotesi del precedente esercizio
e hanno valori minori o uguale di 5 applicare il sottoprogramma COMP
alla sottomatrice di A costituita dagli elementi a.. con l· J. = l 5 eI,J ' , .. -, ,
stampare i risultati ottenuti; altrimenti interrompere l'esecuzione;3) applicare il sottoprogramma a tutta la matrice A precedentemente
trasformata usando i nuovi vettori I = (il + 5, i2 + 5, i3 + 5) e J =
= UI + 5, j2 + 5, j3 + 5) e stampare i risultati ottenuti.Verificare la correttezza del programma usando come dati iniziali la matri-
ce A di elementi a . = _1_ per i = l, ... , lO e j = l, ..., lO e i vettoril,l i + j
1= (1, 3,5), J = (2, 4,5).
se N(x) = O
se N(x) "1= O(f(x) - x)2
N(x)
x
xF(x) =
Xk + 1= F(xk )
che, sotto opportune ipotesi, converge alla soluzione x = s dell'equazione
data.Scrivere un algoritmo che, basandosi sul procedimento iterativo ora descrit-
to, permetta di realizzare quanto segue. Dati in ingresso i valori kmax > O,El > O, E
2~ O e E) ~ O con E2 ed E) non ambedue uguali a zero, determi
nare se esiste un termine xj della successione {xk}, con j E;; kmax' tale che:
Ixj-F(xj_I)IE;;EI e \Xj-xj_IIE;;EIIXj_II+E2·
Se tale xj
esiste, esso è una stima della soluzione dell'equazione data; in
questo caso l'algoritmo deve fornire come risultati i valori di j, x. eJ
Ixj
- F(xj_ I) I· Se tale xj non esiste, l'algoritmo fornisce il risultato j == k
max+ l. Realizzare l'algoritmo ora descritto mediante un sottopro
gramma che preveda fra gli argomenti muti anche il nome della funzione
esterna che descrive f(x).Utilizzare il sottoprogramma per calcolare una soluzione dell'equazionex = e- x con X
o= 0.5, scegliendo valori opportuni per kmax, El' E2, E).
15.10 E' assegnata una matrice reale A quadrata di ordine n, i cui elementi sono
indicati con ai,j' con i, j = l, ... , n. Sono inoltre dati due vettori interi
I = (il' ..., ik) e J = UI' ..., jk) con l :so;; k E;; n, per ognuno dei quali glielementi sono valori distinti compresi fra l ed n ordinati in senso crescente.
Si scriva un sottoprogramma di nome COMP che permetta di «compattare»
nella prime k righe e k colonne della matrice A gli elementi aip,jq con p,
q = l, ... , k. Utilizzare il sottoprogramma con i dati seguenti:
306
Ogni carattere di ogni sottostringa successiva di MESS di lunghezza Q,
indicata per semplicità come' Cl ... c~, viene sostituito nel modo seguente:
se Ci è un carattere blank, allora viene sostituito dalla vi-esima lettera del
l'alfabeto; se invece Ci è la j-esima lettera dell'alfabeto, allora viene sostituito dalla lettera (j + vi)-esima se j + Vi ~ 26 o dalla lettera (j + Vi - 26)
esima se j + Vi > 26 (ricordiamo che l'alfabeto inglese è composto da 26
lettere). Il risultato della codifica di MESS è una stringa, MESS l, composta
da k + l gruppi di Q lettere separati l'uno dall'altro da un carattere blank:il primo gruppo è la parola chiave; i successivi sono ottenuti codificando nel
modo descritto le sottostringhe di MESS. Così, nel nostro caso, la prima
sottostringa di MESS di lunghezza 6 è 'UNvBEL' e viene codificata come
'XVICAQ'; infatti:
U è sostituito da X perché VI = 3 e j = 21;
N è sostituito da V perché v2 = 8 e j = 14;
v è sostituito da I perché v3 = 9;
B è sostituito da C perché v4 = 1 e j = 2;
E è sostituito da A perché Vs = 22 e j = 5;
L è sostituito da Q perché v6 = 5 e j = 12.
La seconda e terza sottostringa di MESS, ossia ' v PANOR' e 'AMA v vv'
vengono sostituite rispettivamente da 'CMJOMW' e 'DUJAVE' .Così il risul
tato è
MESS 1 = 'CHIAVE vXVICAQ vCMJOMW vDUJAVE'
Scrivere un sottoprogramma che, avendo come dati in ingresso una parola
chiave, KEY, e una stringa MESS, di lunghezza qualunque, controlli che la
lunghezza di MESS sia multipla di quella di KEY e, in caso affermativo,
esegua la codifica di MESS e fornisca come risultato la stringa MESS l.
Verificare la correttezza del sottoprogramma usando i dati utilizzati nel
corso di questo esercizio.
15.13 Scrivere un sottoprogramma ALF AB che permetta di ordinare alfabeticamente gli N elementi di un vettore V di tìpo carattere. La lunghezza degli
elementi di V può essere qualunque.Scrivere un programma che utilizzi il sottoprogramma ALFAB per ordinare
gli elementi dei seguenti vettori:
VI = ('GIANNA', 'MARISA', 'ALVARO', 'MATTEO', 'FRANCO')
V2 = ('MATEMATICA', 'STORIAvvvv', 'GEOGRAFIAv', 'ITALIANOvv)
V3 = ('CANE', 'ALCE', 'LUPO', 'GUFO', 'OCA v', 'BUEv', 'BACO').
TI
16Uso flessibile della memoria
16.1. L'istruzione COMMON
La possibilità di strutturare un programma in varie unità, programma princi
pale e sottoprogrammi, è una delle caratteristiche fondamentali del FORTRAN
ed è basata sul concetto di «località» delle variabili che figurano in ogni unità
di programma. D'altra parte le unità di programma devono scambiare informa
zioni fra loro e una prima alternativa per soddisfare questa necessità è offerta dal
meccanismo di associazione fra argomenti muti e argomenti attuali. Tale mec
canismo ha però un certo «costo» in termini di tempo d'esecuzione e occupazione
di memoria: infatti, al momento dell'attivazione di un sottoprogramma l'associa
zione fra ogni argomento muto e il corrispondente argomento attuale viene realiz
zata eseguendo delle operazioni che consentono la trasmissione degli indirizzi dei
parametri attuali dalla unità chiamante al sottoprogramma. In alcune situazioni
può essere vantaggioso evitare questi costi, per esempio quando si debbano tra
smettere gli indirizzi di molti parametri molte volte durante l'esecuzione del
programma. A tale scopo si può usare il meccanismo di spartizione predichiaratadi una zona di memoria da parte di più unità di programma. espresso dall'istruzio
ne dichiarativa COMMON. Usando tale istruzion-e sTp~ò infatti realizzare una se
conda modalità di trasmissione di informazioni fra più unità di programma
che può essere usata insieme o in alternativa alla associazione fra argomenti muti
e argomenti attuali.
I blocchi COMMON
Un blocco COMMON è un insieme di unità di memoria numeriche consecutive
o un insieme di unità di memoria carattere consecutive, alle quali possono acce
dere direttamente più unità di programma. Un blocco COMMON può essere indi
viduato tramite un nome simbolico, detto nome o etichetta del blocco. nel qual
caso il blocco viene detto blocco COMMON etichettato. Il nome di un blocco
COMMON lo distingue dagli altri blocchi dichiarati nel programma e deve essere
diverso dai nomi delle unità che compongono il programma. Un blocco COMMON
308
può anche essere caratterizzato dall'assenza di un nome, nel qual caso il blocco
viene detto blocco COMMON non etichettato.I blocchi COMMON vengono definiti mediante l'istruzione dichiarativa
COMMON, la cui struttura è la seguente:
COMMON I nome} I lista}, Inome2/lista2' ... , Inomen/listandove:
• COMMON è la parola chiave che identifica la frase:
• nomei, con l E;;; i E;;; n, è il nome simbolico di un blocco COMMON oppure è
omesso. Ciascun nomei può essere usato, senza alcuna am biguità, come nome
di variabile nella stessa unità di programma;
• listai' per l E;;; i E;;; n, è una lista di nomi di variabile, nomi di variabile dimen
sionata o dichiaratori di variabile dimensionata. In listai non possono coesistere
entità di tipo carattere con entità di tipo numerico oLo...&li;o; inoltre le variabili
dimensionate che figu;ano in lista. dev~no ave~~-di;~nsionamento-~~~tante:In~------- -1------ _
fine non possono far parte di listai argomenti muti della unità di programmain cui compare la frase COMMON. .-
Per effetto dell'istruzione COMMON alle entità i cui nomi compaiono in listai
vengono riservate unità di memoria consecutive; tali unità di memoria vengono
considerate parte del blocco COMMON individuato dal nome simbolico nomei,oppure di un blocco COMMON non etichettato se nomei è omesso.
Esempio 16.1. La frase
COMMON Il X(50), I NOMEI I Y, Z
dichiara due blocchi COMMON; il primo, non etichettato, comprende i 50 ele
menti del vettore reale X, ovvero 50 unità di memoria numeriche consecutive;
il secondo, etichettato con il nome simbolico NOMEl, contiene le variabili Y e Z
alle quali il compilatore riserva due unità di memoria consecutive. Si osservi che
la frase data è equivalente alla coppia, di istruzioni
DIMENSION X(50)
COMMON Il X, INOMEI I Y, Z
Se in un'istruzione COMMON il primo nome simbohco, nome l , è omesso,
allora possono essere omesse anche le prime due sbarre; così la frase COMMON
dell'esempio precedente equivale alla frase
COMMON X(50), INOME l I Y, Z
Ancora, la virgola che segue ogni lista di nomi può essere omessa; così la frase pre
cedente equivale a
309
COMMON X(50) INOME l I Y, Z
11 nome di un blocco può comparire più volte in una stessa frase COMMON () in
più frasi COMMON nella stessa unità di programma. In questo caso Il' liste asso
ciate al nome del blocco vengono considerate, nell'ordine di apparizione. seg
menti consecutivi di un'unica lista che determina la struttura del blocco. Le stesse
considerazioni valgono per il blocco COMMON non etichettato.
Esempio 16.2. Le sequenze di istruzioni
COMMON A, B I NOME2/ Y, WIl e, D.COMMON E, F I NOME2 I Z
e
COMMON A, B, e, D I NOME2 I Y, WCOMMON E, F INOME2 I Z
sono fra loro equivalenti, ed ambedue hanno lo stesso effetto dell'unica frase
COMMON A, B, C, D, E, F I NOME2 / Y. W. Z
La lunghezza di un blocco COMMON è data dal numero di unità di memoria
che lo compongono; in generale la lunghezza di un blocco è uguale al numero di
unità di memoria consecutive riservate agli elementi della lista associata al suo
nome (cfr. § 16.4).
Esempio 16.3. Con le frasi di specificazione seguenti
CHARAeTER.8 CAR (lO)REAL REX, REYDOUBLE PRECISION DP(15)COMMON IBLOC1/REX,DP. IBLOC2/REY, IBLOC31CAR
vengono definiti tre blocchi COMMON. Ricordando che a un dato in doppia pre
cisione vengono riservate due unità di memoria numeriche consecutive, si deduce
che il primo blocco, BLOCI. è costituito da 31 unità di memoria numeriche; il
secondo, BLOC2, è costituito da l unità di memoria numerica e il terzo, BLOC3,
da 80 unità di memoria carattere. Pertanto i tre blocchi hanno lunghezza rispet
tivamente 31, l ed 80.
16.2. Utilizzazione dei blocchi COMMON
Blocchi COMMON etichettati
In più unità di programma si possono definire blocchi COMMON etichettati
~IIII
~"
:11
blocco COMMON di nome UNO
X(\) Y(\)
X(2) Y(2)
X(3) Y(3)
X(4) Y(4)
X(S) ZO,I )
X(6) Z(2,I)
X(7) Z(1,2)
X(8) Z(2,2)
I
ii(
"
310
con lo stesso nome. In questo caso i blocchi devono essere costituiti con lo stesso
tipo di unità di memoria (carattere o numerico) e devono avere la stessa lunghez
za. Durante l'esecuzione del programma tali blocchi occupano la medesima zona
di memoria. Così, se in più unità di programma si definiscono blocchi COMMON
_con lo ~tesso nome, SI definisce di fatto un gruppo di celle di memoria consecu
tive i_contenuti delle quali sono direttamente utilizzabili da queste unità. Le
liste associate al nome del blocco nelle diverse unità di programma specificano
i nomi locali che ogni unità utilizza per identificare le celle del blocco.
Esempio 16.4. Un programma comprende il programma principale di nome
MAIN e i due sottoprogramrni SUBI e SUB2 seguenti:
PROGRAM MAINCOMMON /UNO/X(8), /DUE/N, M
END
SUBROUTINE SUBICOMMON /UNO/Y(4), Z(2, 2)
END
MAIN SUBI MAIN SUB
~~
blocco COMMON di nome DUE
311
SUBROUTINE SUB2COMMON /DUE/I, J
END
Nel programma vengono definiti due blocchi COMMON, di nomi UNO e DUE,
di lunghezza B e 2 rispettivamente. II primo blocco è definito nel programma pnn
cipale e nel sottoprogramma SUB l e le celle del blocco sono identificate con i
nomi Xt l ), X(2), ... , X(B) e Y( I), ... , Y(4), Z(l, I), .. " Z(2, 2) rispettivamente
nelle due unità dr programma. Al secondo blocco invece hanno accesso il program
ma principale e il sottoprogramma SUB2 che ne identificano le celle con i nomi
N, M e I, J rispettivamente. Così, i valori attribuiti nel programma principale
agli elementi del vettore X sono direttamente utilizzabili dal sottoprogramma
SUB I come valori degli elementi di Y e Z, e viceversa. Analogamente i valori asse
gnati ad N e M nel programma principale vengono direttamente trasmessi al sotto
programma SUB2 che vi fa riferimento con i nomi I e J, e viceversa. In fig. 16.1
sono schematicamente rappresentati i due blocchi COMMON: ogni rettangolo
rappresenta una cella di memoria e i nomi all'interno del rettangolo sono i nomi
che identificano la cella nelle diverse unità di programma.
Figura 16.1. Rappresentazione dei blocchi COMMON definiti nell'esempio 16.4.
Il blocco COMMON non etichettato
1 blocchi COMMON /IO/I etichettati definiti iII più unità di programma pOSSOIlO
avere lunghezze diverse; iII ogni caso la loro prima unità di memoria è la stessa e
quindi essi definiscono zone di memoria che si sovrappongono del tutto o in
parte. In altri termini in un programma si può definire una zona della memoria. il
blocco COMMON non etichettato. costituita da un numero di unità di memoria
pari alla massima lunghezza dei COMMON non etichettati dichiarati nelle singole
(
. unità di programma; ognuna di queste unità può direttamente utilizzare i conte
nuti delle prime Q unità di memoria del blocco se Q è la lunghezza del blocco
COMMON non etichettato in essa dichiarato.
Esempio 16.5. In fig. 16.2 sono rappresentate quattro unità di uno stesso pro
gramma. ognuna delle quali contiene la specificazione di un blocco COMMON
non etichettato. Nei sottoprograrnmi NO\fE I e ~O\fE3 il blocco ha 11111~hena
6, mentre in NOME2 e NOME4 ha lunghezza 2 e 4 rispettivamente. Pertanto ri
sulta definito nel programma un blocco COMMON non etichettato di lunghezza
6; le unità NOMEI e NOME3 hanno accesso a tutte le celle del blocco. mentre
NOME2 può accedere soltanto alle prime due e NOME4 soltanto alle prime
312 313
NOMEI NOME2 NOME3 NOME4
SUBROUTINE NOME lREAL A, B, CCOMMON A, B, C(4)
(
COMMON sono uno strumento molto meno flessibile delle liste di argomenti;!così, per esempio, in essi non devono figurare variabili dimensionate con di
mensionamento variabile e ciò può limitare le possibilità di utilizzo di un sottoprogramma.
Esempio 16.6. Consideriamo il programma di fig. 16.3, costituito dal sottopro
gramma ORD che permette di ordinare in senso crescente i contenuti degli N elementi di un vettore X e dal programma principale MAIN che lo utilizza. Le due
unità di programma comunicano attraverso la lista degli argomenti. Possiamomodificare le unità ORD e MAIN in modo da ottenere un programma principaleMAINI e un sottoprogramma ORDI che sono analoghi ai precedenti ma utilizzano come canale di comunicazione un blocco COMMON non etichettato (cfr.fig. 16.4). Si può notare che la frase
REAL X(N)
del sottoprogramma ORD viene sostituita dalla frase
REA L X(SO)
nel sottoprograrnma ORD 1, in quanto il vettore X fa parte di un blocco COMMON
A A M(l) C(l)
B B M(2) C(2)
C(l) M(3) C(3)
C(2) M(4) C(4)
C(3) M(S)
C(4) M(6)END
SUBROUTINE NOME4REAL CCOMMON C(4)
END
SUBROUTINE NOME3INTEGER MCOMMON M(6)
END
SUBROUTINE NOME2REAL A, BCOMMON A, B
END
Figun 16.2. Sottoprogrammi e blocco COMMON deU'esempio 16.5.
quattro. Si noti che nel sottoprogramrna NOME3 le celle sono individuate con
nomi di tipo intero, mentre nelle altre unità si utilizzano nomi di tipo reale.
/
1 Osservazione. Si not.i che l'associazione che viene stabilita fra le variabi!i !,resen~~
... in un blocco ~()~~ON che figura in più unità di programma è indi~~nte dalI tipo di queste variabili: è quindi estremamente importante che il programmatore
ponga moltaattenzione ai possibili effetti non desiderati derivanti dal disaccordo
in tipo fra variabili che spartiscono le medesime unità di memoria.
l blocchi COMMON possono essere utilizzati con un duplice scopo. Attraverso
la definizione di zone di memoria utilizzabili da più unità di programma si può
ridurre talvolta la quantità di memoria necessaria alla esecuzione di un program
ma. D'altra parte i blocchi COMMON costituiscono veri e propri canali di comu
nicazione fra unità di programma e possono essere usati per scam bio di informazioni. Rispetto all'associazione fra parametri muti e parametri attuali, l'uso dei
blocchi COMMON presenta il vantaggio di una maggior velocità di esecuzione;infatti in questo caso non si eseguono operazioni per realizzare la trasmissionedelle informazioni in quanto i blocchi vengono definiti dal compilatore e dallinker nelle fasi che precedono l'esecuzione. Osserviamo però che i blocchi
j
PROGRAM MAINREAL X(SO)READ -. N, (X(I), I = l, N)WRITE(*, 3)(X(I), I = l, N)
3 FORMAT(lX, 'vETTORE DA RIORDINARE' / S(lX, EI3.6)CALL ORO (X, N)WRlTE(*,5) (X(I), I = l, N)FORMAT(l X, 'VETTORE RIORDINATO' / S(lX, EI3.6»STOPEND
SUBROUTINE ORD(X, N)REAL X(N)
C RIORDINAMENTO IN SENSO CRESCENTEC DEGLI ELEMENTI DEL VETTORE X
0010 1=I,N-IXMIN = X(I)DO 20 J = I + l, NIF (X MIN.GT.x(J)) XMIN = X(J)
20 CONTINUEX(I) = XMIN
IO CONTINUERETURNEND
Figura 16.3. Scambio di informazioni fra unità di programma attraverso la lista degli argomenti(esempio 16.6)
314
PROGRAM MAINIREAL X(50)COMMON N, X
CALL ORDI
END
SUBROUTINE ORDIREAL X(50)COMMON N,X
END
Figura 16.4. Scambio di informazioni fra unità di programmaattraverso un blocco COMMON (esempio 16.6).
e non può quindi avere dimensionamento variabile. Si osservi che questa forma
di dimensionamento potrebbe essere mantenuta lasciando X fra gli argomenti
muti di ORD e mettendo N in un blocco COMMON.
Osserviamo che in alcune situazioni l'uso dei blocchi COMMON può rivelarsi
molto vantaggioso se non si vogliono modificare sottoprogrammi già scritti.
Esempio 16.7. Consideriamo la seguente funzione della variabile x
(I + a)f(x) = x2 - 2ax + --- - 2a
log x
315
PROGRAM MALFA
COMMON /MAINFX/ALFA
PARAMETER (A = IO., B = 100.)EXTERNAL FXALFA
REA D e , N, EPS
H = (B - A)/N
ALFA = O.
DO 20 1 = l, IO
ALFA = ALFA + 0.1
XO= ACALL SGNI (XO, XN, H, N, EPS, JCS, FXALFA)
WRITE (., 3), ALFA, JCS
3 FORMAT(/ IX, 'ALFA =', F3.I, 5X. 'JCS =',15)
20 CONTINUE
STOP
END
FUNCTION FXALFA(X)
COMMON /MAINFX/ALFAFXALFA = X • X - 2.• ALFA. X + (1. + ALFA)/LOG(X) - 2.• ALFA
RETURN
END
Osserviamo che il programma è composto dal programma principale MALFA
e dai sottoprogrammi SGN l ed FXALFA. L'uso del blocco COMMON ci con
sente di «scavalcare» SGN l e passare l'informazione relativa ad ALFA diret
tamente da MALFA a FXALFA. In fig. 16.5 rappresentiamo schematicamente
il modo in cui la memoria viene utilizzata e il modo in cui avviene la trasmissione
di informazioni fra le varie parti della memoria.
Figura 16.5. Utilizzazione della memoria e scambio di infonnazioni fra unità di programma
(cfr. es. 16.7).
dove a è un parametro reale che può assumere i valori 0.1, 0.2, ... ,0.9, l. Fissatol'intervallo di estremi a = l O, e b = 100., e assegnati i valori n > O e € > O, si
vuole utilizzare il sottoprogramma SGN l dell'esempio 15.15 per studiare il com
portamento di f(x), per ogni valore di a, sui punti xi = a + ih, con i = O, ..., n e
h = (b - alIno
La SUBROUTINE SGN l richiede la definizione di un sottoprogramma di tipo
FUNCTION, con un unico argomento muto che rappresenta la variabile indi
pendente x, Nel nostro caso quindi, non potendo utilizzare la lista degli argo
menti per trasmettere alla funzione il valore di a, dovremmo definire per ogni
valore di a un sottoprogramma FUNCTION distinto. Si può evitare tale dispen
dioso modo di procedere ricorrendo alla definizione di un blocco COMMON
opportuno. Quanto detto è esemplificato nel seguente programma principale e
nel sottoprogramma FXALFA.
Memoria locale Unità di programma
MAIN
Blocchi COMMON
accesso di una unità
- di programma alla
sua memoria locale
scambio di informazioni
~-----. tramite la lista di
argomenti muti e attuali
accesso al blocco
COMMON
317
Figura 16.6. Effetto dell'istruzione EQUIVALENCE dell'esempio 16.8.
precedenti figure, ogni rettangolo rappresenta una unità di memoria, e i nomi alsuo interno sono i nomi usati per identificare questa unità; nel caso della variabilecomplessa OMEGA, il nome identifica due unità di memoria numeriche.
Si osservi che l'eventuale spartizione di una o più unità di memoria da parte dientità di tipo diverso non implica alcuna operazione di conversione. Osserviamo
inoltre che, evidentemente, un'istruzione EQUIVALENCE non deve implicaresovrapposizioni di unità di memoria che devono essere distinte o la «separazione»
di unità di memoria che devono essere consecutive. Pertanto sono sbagliate dichiarazioni del tipo
REL(I)
REL(3)
REL(2)
REL(4)I----OMEGA-
ALFA (1 : 1) CAR (1)
ALFA (2: 2) CAR (2)
ALFA (3 : 3) CAR (3)
ALFA (4: 4) CAR (4)
ALFA (5: 5) CAR (5)
ALFA (6: 6)
mente 6 e 5 unità di memoria carattere, hanno in comune le prime 5 di queste;pertanto il nome CAR (1). con 1 :E;;; I :E;;; S, identifica la stessa unità di memo
ria identificata dal nome ALFA (I : I). Ancora, la variabile di tipo complessoOMEGA occupa due unità di memoria numeriche consecutive, mentre REL(3)è il terzo elemento del vettore reale REL che ha ampiezza 4; pertanto le unitàdi memoria occupate da OMEGA coincidono con quelle occupate da REL(3)e REL(4). Infine, i tre nomi I, J e K identificano la stessa cella di memoria. Infig. 16.6 si rappresenta in modo schematico l'effetto ora descritto. Come nelle
316
dove:
• EQUIVALENCE è la parola chiave che identifica la frase;
• per ogni i, l <; i .;; n, listai è una lista composta da almeno due nomi, separatida virgole; listai può contenere nomi di variabile, nomi di variabile dimensionata,nomi di elementi di variabile dimensionata con indici costituiti da espressioni
costanti intere, e nomi di sottostringhe. L'occorrenza in listai di un nore di variabile dimensionata è equivalente all'occorrenza del suo primo elemento. Nonpossono coesistere in listai entità di tipo carattere con entità di tipo numericoo logico; inoltre non possono figurarvi argomenti muti della unità di programmain cui la frase EQUIV ALENCE compare.
Per effetto della dichiarazione EQUIVALENCE tutte le entità che compaionoin ciascuna listai' con l .-; i <;; n, hanno in comune la prima unità di memoria.Da ciò può seguire che due o più entità in una stessa lista spartiscano, oltre allaprima, altre unità di memoria.
16.3. L'istruzione EQUIVALENCE
L'idea della spartizione di una cella di memoria da parte di più variabili espressadalla frase COMMON si trova anche nella frase. dichiarativa EQUIVALENCE.La differenza fondamentale rispetto alla frase COMMON risiede nel fatto checon la frase EQUIVALE:~ç~ viene dichiarata la spartizione di una zona dellamemoria da parte di più variabtl; nella medesima unità di tuozmmma. Esi
stono varie circostanze nelle quali può risultare utile sfruttare le possibilità offerte dalla dichiarazione EQUIVALENCE; essa infatti consente di riferirsi allamedesima quantità con nomi diversi ed è quindi utilizzabile, ad esempio, quandosi vuole risparmiare memoria in presenza di grandi quantità di dati. In quest'ul
timo caso, quando ad esempio una variabile dimensionata sia già stata elaborata
e la sua presenza in memoria non sia ulteriormente necessaria, un'altra variabiledimensionata, il cui nome ci interessi mantenere distinto da quello della prima,
può occupare in tutto o in parte lo spazio di memoria occupato dalla prima.La forma della frase EQUIVALENCE è la seguente:
EQUIVALENCE (listai)' (list~)•...• (listan
)
Esempio 16.8. Consideriamo le seguenti istruzioni:
CHARACTER ALFA. 6, CAR(5). IREAL REL(4)COMPLEX OMEGAEQUIVALENCE (ALFA, CAR), (OMEGA, REL(3», (I, J, K)
L'effetto di queste frasi è il seguente: ALFA e CAR, che occupano rispettiva-
DIMENSION A(2)EQUIVALENCE (A(l), B), (A(2), B)
oppure
REAL A(2)COMPLEX C(2)EQUIVALENCE(A(I), C(I »,(A(2), C(2»
':i. [I
:1
I,I
318
Anche alla luce delle precedenti osservazioni, occorre molta attenzione nell'utilizzare la frase EQUIV ALENCE soprattutto in relazione a variabili dimensionate.
Esempio 16.9. Si considerino le seguenti frasi di specificazione
REAL A(6), B(2, 3), C(6)EQUIVALENCE (A, B), (B(I, 2), C(3»
Il significato di questa frase EQUIVALENCE può essere il seguente: il primo elemento del vettore A ed il primo elemento della matrice B occupano la medesima
cella di memoria ed il primo elemento della seconda colonna della matrice B
occupa la stessa cella del terzo elemento del vettore C. Esaminiamo però gli effetti
implicitamente derivanti dalla frase EQUlVALENCE, dovuti al fatto che A, B e
C sono variabili dimensionate ed occupano ciascuna 6 unità di memoria conse
cutive. L'effetto complessivo nel nostro caso è quello descritto in fig. 16.7, dove
si nota in particolare che dalla sovrapposizione fra B( l, 2) e C(3) segue la sovrap
posizione totale fra la matrice B e il vettore C. Pertanto le frasi considerate sonoequivalenti alle frasi
REAL A(6), B(2, 3), C(6)EQUIVALENCE (A, B, C)
Esempio 16.10. Le dichiarazioni seguenti
REAL A(2, 2), B(2, 2)EQUIVALENCE (A(I, 2), BO, I»
producono l'effetto schematizzato in fig. 16.8, ovvero la sovrapposizione fra laseconda colonna della matrice A e la prima colonna della matrice B.
1319
16.4. Interazione fra istruzioni COMMON ed EQUIVALENCE
E' possibile che una variabile, dimensionata o non dimensionata, figuri in una
frase COMMON e in una frase EQUIV ALENCE nella stessa unità di programma,
purché l'effetto congiunto delle due frasi non dia luogo alle seguenti situazioni
non consentite. Innanzitutto un'istruzione EQUIVALENCE non deve creare sovrapposizioni fra blocchi COMMON distinti; per esempio è sbagliata la compre
senza nella stessa unità di programma delle seguenti frasi
COMMON!COMI! A(lOO), B(lOO)COMMON!COM2! X, YEQUIVALENCE (B(lOO), X)
In questo caso, infatti, l'ultima cella di memoria del blocco di nome COM I
si sovrapporrebbe alla prima cella del blocco di nome COM2. Si osservi inoltreche dall'interazione tra una frase COMMON e una frase EQUlVALENCE può
seguire un allungamento di un blocco COMMON. Per spiegare in cosa consistequesto fenomeno conviene ricorrere ad un semplice esempio.
Esempio 16.11. Consideriamo le seguenti istruzioni
REAL D(3)COMMON IX! A, B, CEQUIV ALENCE (C, D(I»
Per effetto della frase EQUIV ALENCE la terza unità di memoria del blocco
COMMON coincide con l'unità di memoria riservata al primo elemento del vet
tore reale D. In questo caso anche i restanti due elementi di D vengono considerati parte del blocco COMMON (cfr. fig. 16.9.a); pertanto le istruzioni datesono equivalenti alle seguenti
A(I) B(l,I) C(I)
A(2) B(2,1) C(2)
A(3) B(I,2) C(3)
A(4) B(2,2) C(4)
A(5) B(I,3) C(5)
A(6) B(2,3) C(6)
Figura 16.7. Effetto della fraseEQUlVALENCE nell'esempio 16.9.
A(l,I)
A(2,1)
A(l,2) B(I,I)
A(2,2) B(2,1)
B(I,2)
B(2,2)
Figura 16.8. Effetto della fraseEQUIVALENCE nell'esempio 16.10.
REAL D(3)COMMON IX! A, B, OEQUIVALENCE (C, 0(1»
e il blocco COMMON ha lunghezza 5 anziché lunghezza 3 come risulterebbedalla sola frase
COMMON IXI A, B, C
Ancora. la sequenza di istruzioni
REAL 0(3)COMMON IX! A, B, CEQUIVALENCE (B, O (I»
equivale alla sequenza
e in questo caso il blocco COMMON ha lunghezza 4 (cfr. hg. 16.9.b).
REAL 0(3)COMMON /X/ A, DEQUIVALENCE (8, D(1», (C, 0(2» i
l
III
A D(3)
B
C
0(1)
D(2)
Figura 16.10. Allungamento non consentito di un blocco COMMON.
321
La frase DATA consente di predefinire, ossia definire prima dell'esecuzione,
in fase di compilazione, il valore di una variabile, di una variabile dimensionata,
di un elemento di una variabile dimensionata, di una sottostringa. I valori asse
gnati con una frase DATA restano inalterati per la durata dell'esecuzione dell'inte
ro programma, a meno che non vengano esplicitamente modificati nell'unità di
programma in cui la frase DATA compare.La frase DATA è una frase non eseguibile che può apparire in qualsiasi punto
di una unità di programma dopo le frasi di specificazione e prima della END.
Tale frase ha la forma seguente:
16.5. La frase DATA
b)
A
8 D(1)
C 0(2)
0(3)
a)
Figura 16.9. Allungamenti del blocco COMMON nell'esempio 16.11.
A
8
C 0(1)
D(2)
0(3)
320
L'allungamento di un blocco COMMON etichettato per effetto di frasi
EQUIVALENCE in una unità di programma è consentito purchè sia rispettata la
regola secondo la quale i blocchi COMMON con lo stesso nome definiti in unità
di programma diverse devono avere la stessa lunghezza. In ogni caso, anche per il
blocco COMMON non etichettato, vale la seguente restrizione: un blocco COMMON
può essere allungato soltanto «a destra», ovvero con l'aggiunta di unità di memo
ria successive all'ultima. Pertanto è sbagliata la sequenza di istruzioni
REAL D(3)COMMON /X/ A, B, CEQUIVALENCE (A, D(3»
secondo la quale l'elemento D(3) si sovrappone alla prima unità di memoria del
blocco COMMON; ciò provocherebbe un allungamento non consentito «a sini
stra», come illustrato in fig. 16.10.
dove:• DATA è la parola chiave che identifica la frase;• le virgole che separano ogni coppia nlistaJvlistaJ dalla successiva, possono
essere omesse;• ciascuna nlista
i, per I ~ i ~ n, è una lista di nomi di variabile; nomi di variabile
dimensionata, nomi di elementi di variabile dimensionata, nomi di sottostringa
e liste con DO-implicito. Le espressioni indice nei nomi di elementi di variabile
dimensionata e le espressioni di sottostringa nei nomi di sottostringa devono
essere espressioni costanti intere;• ciascuna vlista
i, per I ~ i ~ n, è una lista di costanti, nomi simbolici di costante,
o simboli della forma r * c, dove r è (un nome simbolico di) una costante intera
non nulla senza segno e c è una costante o un nome simbolico di costante. La
presenza di un simbolo r * c è equivalente alla presenza di r costanti successive
uguali a c separate da virgole. Tenendo presente che ogni nome di variabile dimensionata in nlista
iè equivalente alla lista dei nomi dei suoi elementi nell'ordine in
,:1
1
322
cui compaiono in memoria, il numero di valori costanti espressi in nlista i deve
essere uguale al numero di componenti di nlista.. Infatti viene stabilita una corri
spondenza uno-a-uno fra gli elementi di nlista i e quelli' di vlista j e ogni elemento
di nlista. viene predefinito con il corrispondente valore in vlista j . Di questa prede-I . .
finizione si tiene conto attraverso la tavola dei sim boli (cfr. cap. 2) che in COrrI-
spondenza di ogni entità presente in una frase DAT A riporta. oltre all'indirizzo
della sua prima unità di memoria, anche il suo valore iniziale. Da quanto detto
segue che ad ogni elemento di tipo logico o carattere in nlista i deve corrispondere
un valore dello stesso tipo in vlista.. Si osservi inoltre che la predefinizione di un
elemento di tipo carattere avviene secondo le regole dell'assegnazione carattere
e quella di un elemento di tipo numerico può implicare un'operazione di conver
sione secondo le specifiche della frase di assegnazione aritmetica.
Si osservi che la frase DATA non può essere usata per predefinire entità che
facciano parte di un blocco COMMON non etichettato o della lista di argomenti
muti nella stessa unità di programma. Le entità che fanno parte di un blocco
COMMON etichettato possono invece essere predefinite soltanto nel corpo di un
sottoprogramma BLOCK DATA, come vedremo nel paragrafo successivo.
Esempio J6. J2. Sono corrette le seguenti istruzioni:
DATA UNO, DUE, TRE 11.,2.,3./, I, J, K I 3 * O
DATA TRE. CINQUE I 3,5
DIMENSION V(lO, IO), U(l5)DATA V I 100 * 0./, U I IO * O., 1.,2.,3.,4.,5./
CHARACTER * 2 MAT (3, 3), VARDATA MAT(I, l), MAT(2, 2), MAT(3, 3), VAR 14 * 'UN'
Sono invece sbagliate le seguenti:
DATA A,B 13*0.51
DOUBLE PRECISION D(5,5)DATA D I 20*0.5D-21
CHARACTER * 4 NOMEDATA NOME,X I 3.2, 'ANNA'I
Infatti nei primi due casi nlista i e vlista i non contengono lo stesso numero di
elementi, mentre nel terzo la variabile NOME, di tipo carattere, viene predefinita
con un valore reale e la variabile reale X con un valore di tipo carattere.
I\
I
323
Esempio J6.13. Consideriamo le seguenti istruzioni:
REAL B(l5,I5)CHARACTER * 6 NOME(41DATA B 1225 * 0./, NOMEI 'GUIDO', 'BRUNO', 'GIULIO', 'LAPO'/
A tutti gli elementi della matrice B viene assegnato in fase di compilazione il
valore zero, mentre gli elementi del vettore carattere NOME conteranno all'inizio
dell'esecuzione le stringhe 'GUIDOv', 'BRUNOv', 'GIULIO, ' LAPOvV. Infatti
i contenuti di B e NOME risultano definiti come se venissero eseguite le frasi diassegnazione seguenti:
DOlO 1==1,15DO IO J == l, l 5
IO B(I, J) == O.NOME(I) == 'GUIDO'NOME(2) == 'BRUNO'NOME(3) == 'GIULIO'NOME(4) == 'LAPO'
Osserviamo che i valori preassegnati agli elementi di B e di NOME possono es
sere modificati durante l'esecuzione del programma.
Come l'esempio precedente suggerisce, le frasi DATA possono essere vantag
giosamente utilizzate per predefinire variabili dimensionate di grosse dimensioni;
in questi casi infatti la predefinizione in fase di compilazione permette un notevo
le risparmio di tempo rispetto, per esempio, all'esecuzione di un gran numero di
frasi di assegnazione. Talvolta la frase DATA può essere usata con uno scopo ana
logo a quello dell'istruzione PARAMETER, ovvero per poter usare nel corpo di
una unità di programma un nome simbolico per riferirsi ad una quantità che non
cambia durante l'esecuzione del programma. Così. per esempio, le due frasi
DATA I EPS I LE -0.5PARAMETER (EPS == LE - 0.5)
consentono am bedue di utilizzare il nome sim bolico EPS in luogo della costante
I.E - 0.5. D'altra parte le due frasi non sono equivalenti; infatti nel primo caso
EPS è un nome di variabile e il suo valore può essere modificato successivamente
durante l'esecuzione. mentre nel secondo caso EPS è un nome di costante.
Liste con DO-implicito nella frase DAT A
In una frase DATA possono figurare liste con DO-implicito con lo stesso signi
ficato ad esse attribuito nelle liste di I/O. Lo standard F77 impone però alcune re-
------.-...._------ .- .._-- -----
324
strizioni alle liste con DO-implicito presenti nelle frasi DATA; esse infatti devonoavere la forma seguente:
dove:• Y è la lista del DO-implicito in cui possono figurare soltanto nomi di elementi
di variabile dimensionata, e, eventualmente, altre liste con DO-implicito;
• i è la variabile del DO-implicito e deve essere una variabile di tipo intero;
• mI' m2, m3 hanno lo stesso significato attribuito ai simboli vI' v2, v3 nelle listecon DO-implicito nelle frasi di I/O; mI' m2 ed m3 devono essere espressioni costan
ti intere se la lista con DO-implicito non è contenuta in un'altra lista con DO-im
plicito; altrimenti mI' m2 ed m3 possono essere espressioni intere che contengonocostanti, nomi simbolici di costanti e le variabili (ovviamente diverse da i) delle
liste con DO-implicito più esterne. In ogni caso i valori di mI' m2 , m3 devono
essere tali da implicare almeno una ripetizione della lista.
Esempio 16.14. Le frasi
PARAMETER (N = 5)DATA (V(I), l = l, N) /5.0./
sono corrette. In particolare è corretto l'uso del nome simbolico N nella lista con
DO-implicito in quanto N è un nome di costante. E' invece sbagliata la sequenza
DATA N / 5/DATA (V(I), l = l, N) /5.0./
perché in questo caso N è un nome di variabile e non è la variabile di una lista
con DO-implicito esterna a (V(I), I = l, N).
Esempio 16.15. La frase
DATA «X(K, J), J = K, 5), K = 1,5) /15 * 0./
è corretta e definisce come zero i quindici elementi della matrice X che compon
gono la lista con DO-implicito. Lo stesso effetto, in fase di esecuzione, si otterreb
be con le frasi:
00 15 K = 1,500 15 J = K,5
15 X(K.J)=O.
Si osservi che la definizione della variabile di una lista con DO-implicito nella
frase DATA non implica alcuna predefinizione per una eventuale variabile con
325
il medesimo nome che figuri nella medesima unità di programma.
Osserviamo infine che la frase DATA era prevista anche in F66, ma con alcune
differenze rispetto alla forma e alle modalità di utilizzo qui descritte (cfr. appendice A2).
16.6. Sottoprogrammi BLOCK DATA
Se si vuole predefinire con una frase DATA un'entità che fa parte di un bloccoCOMMON etichettato, si deve utilizzare un opportuno sottoprogramma di tipo
BLOCK DATA. Ricordiamo che non è consentita la predefinizione di entità chefigurano in un blocco COMMON non etichettato.
L'unico scopo dei sottoprogrammi BLOCK DATA è quello di predefinire entitàche fanno parte di blocchi COMMON etichettati; essi sono quindi sottoprogramminon eseguibili che non possono essere utilizzati da altre unità di programma in
fase di esecuzione ma vengono trattati direttamente in fase di compilazione.La prima frase di un sottoprogramma BLOCK DATA ha la forma seguente:
BLOCK DATA nome
dove:
• BLOCK DATA è la parola chiave che identifica la frase;
• nome è un nome simbolico che può essere omesso. Se presente, nome è il
nome simbolico che identifica il sottoprogramma e lo distingue da tutte le altre
unità di programma; esso non può essere usato a nessuno scopo nel corpo del
sottoprogramma. In un programma possono esistere più sottoprogrammi di tipoBLOCK DATA con nomi diversi ed uno solo senza nome.
Il corpo di un sottoprogramma BLOCK DATA deve terminare con la frase
END e può contenere oltre a questa soltanto frasi di specificazione di tipo,frasi IMPLICIT, PARAMETER, DIMENSION, COMMON, EQUIVALENCE,SAVE (cfr. cap. 17) e, naturalmente, frasi DATA.
Esempio 16.16. Il sottoprogramma seguente
BLOCK DATACHARACTER • 6 CAR, MOTS(150)REAL A(IO, io), B(IO)COMMON / BLOCI / A, B,/ BLOC2 / MOTS,CAROATA A, B /110.0.5/, MOTS/150. 'INIZIO'/END
permette di predefinire con i valori presenti nella frase DATA i contenuti dellelocazioni di memoria che costituiscono il blocco COMMON di nome BLOCl,
I,! 326
identificate in questa unità di programma come elementi delle variabili dimensio
nate A e B. Ancora, la frase DATA predefinisce gli elementi del vettore carattere
MOTS che fa parte del blocco COMMON di nome BLOC2, ma non la variabile
CAR che occupa le ultime sei unità di memoria del blocco. E' evidente che
i valori preassegnati in questo sottoprogramma alle variabili A, B sono direttamen
te utilizzabili all'inizio della esecuzione da tutte le unità di programma al cui
interno sia definito un blocco COMMON di nome BLOCl; queste unità potranno
fare riferimento a tali valori con i nomi locali usati per identificare le celle del
blocco. Analogamente i valori memorizzati negli elementi del vettore MOTS
sono disponibili all'inizio dell'esecuzione per tutte le unità di programma che
fanno riferimento al blocco COMMON di nome BLOC2.
Esempio 16.17. Consideriamo il sottoprogramma:
BLOCK DATA BLOCDCHARACTER * lO SETTIM (7), MESE (12)INTEGER GMESE(l2)COMMUN I NOMI I SETTIM, MESE, I GIORNI I GMESEDATA SETTlM I 'LUNEDI"', 'MARTEDI"', 'MERCOLEDI''', 'GIOVEDI'",
*'VENERDI"', 'SABATO', 'DOMENICA' l, MESE I 'GENNAIO', 'FEBBRAIO'.*'MARZO', 'APRILE', 'MAGGIO', 'GIUGNO', 'LUGLIO', 'AGOSTO',*'SETTEMBRE', 'OTTOBRE', 'NOVEMBRE', 'DICEMBRE' I,*(GMESE(I), I = 1,12) I 31, 28, 31,30, 31 ,30, 2 * 31,30,31,30,31 I
END
Tale sottoprogramma BLOCD predefinisce tutti gli elementi dei vettori carat
tere SETTIM e MESE e quelli del vettore intero GMESE; in altri termini ven
gono predefinite tutte le unità di memoria dei blocchi COMMON di nomi NOMI
e GIORNI.
Si osservi che due o più sottoprogrammi BLOCK DATA in uno stesso pro
gramma non possono fare riferimento a blocchi COMMON etichettati con lo
stesso nome.
327
Esercizi
16.1 Segnalare gli errori presenti nelle seguenti frasi COMMON:
a) COMMON A, B, C I BLl I N, A
b) COMMON Il N, M, I.
c) COMMON IVAR I D(l 00), B(I)d) DIMENSION A(200)
COMMON A(50)
e) DIMENSION V<N)
COMMON I VAR I V
f) FUNCfION BETA (X, Y)
COMMON MAT( l O, IO), X
g) CHARACTER * 80 FRASE
COMMON FRASE (l : 20)
h) CHARACfER * 30 PAESE
INTEGER N
COMMON PAESE, N
16.2 Rappresentare graficamente i blocchi COMMON definiti nel seguente pro
gramma e i nomi usati nelle diverse unità per riferirsi alle locazioni deiblocchi
PROGRAM MAIN
COMMON A, X(5), YIBLl IC, Z(5, 5)/BL2/N, I, K
END
FUNCfION FUNZ (L, M)
COMMON A/BLl/C, Z(5, 5)
COMMON/BL3/ALFA
END
SUBROUTINE SUB
COMMON A, B, C, D, E, F, G/BL2/N(3)
COMMON/BL31ALFA
END
16,3 Se in una unita dI programma il blocco COMMON di nome PROVA è definito dalla frase
COMMON I PROVA I C(5. 4), A
con C ed A reali, indicare quali fra le seguenti definizioni possono esserepresenti in un'altra unità dello stesso programma:
328 329
a) COMMON / PROVA / C(5, 5), Ab) COMMON / PROVA / A(5), B(5), C(5, 2), D
c) COMMON / PROVA / C(5, 4)
d) COMMON / PROVA / X(2l)e) COMMON / PROVA / X(5), Y(5), Z(5), W(5)
f) COMMON / PROVA / A, C(5, 4)
g) COMMON / PROVA / M(2l)
16.5 Scrivere un programma che, fissato Q = 15 e due vettori u e v di IRn. usiil sottoprogramma MF2 dell'esempio 15.16 per determinare fra i punti
wk = ~ u + ( l - ~) v, O~ k ~ Q,quello a cui corrisponde il più piccolo
valore della norma euclidea della funzione data F n (x). Questa funzione
associa ad un vettore x di componenti xl' ... , xn
il vettore Y le cui componenti Yl' ... , Yn sono definite da:
16.6 Modificare il sottoprogramma MAXMIN dell'esempio 14.3 e il programma
principale dell'esempio 14.8 in modo che lo scambio di informazioni fra le
due unità di programma avvenga tramite blocchi COMMON.
Si vuole che il programma risolva il problema per n = 2, 3,4,5; in ogni caso
il vettore u deve avere elementi tutti uguali a 0.5 e il vettore v deve avereelementi tutti uguali a 1. Inoltre si deve definire un solo sottoprogramma
che realizzi le funzioni F2(x), F3(x). F4(x) e Fs(x). (Suggerimento: fareuso della frase COMMON, cfr. esempio 16.7).
I :, I\ !
per i = 2, ... , n
per i = 1n
Yj =- 1 + nXjj= I
n
Yj = xi + L Xj - (n + 1)j= I
16.7 Modificare la funzione esterna MMV e il programma principale USOMMVdell'esempio 15.8 in modo che:
a) soltanto il vettore X resti fra gli argomenti muti di MMV e il valore di
N venga trasmesso tramite un blocco COMMON;
b) tutte le informazioni fra le due unità di programma vengano trasmesseattraverso blocchi COMMON.
16.8 Scrivere opportune frasi dichiarative per soddisfare le seguenti richieste:
a) due matrici rettangolari specificate dalla frase
REAL A(20, 20), B(20, lO)
si sovrappongono in modo tale che gli ultimi 200 elementi di A,coincidonocon gli elementi di B;
b) gli elementi di una matrice MAT di lO righe e lO colonne sono indivi
duabili come elementi di un vettore MATV ET ;
c) i tre piani della variabile VAR3 dichiarata come
REAL VAR3 (lO, 10,3)
possano essere trattati come 3 matrici di lO righe e lO colonne.
PRIMA TERZA SESTA NONA
l(l ) M(l,l) I K(l)
1(2) M(2,1) J K(2)
1(3) M(3,1) K K(3)
1(4) M(1,2) M(l) L(l)
1(5) M(2,2) M(2) L(2)
1(6) M(3,2) M(3) L(3)
1(7) M(1,3) L(4)
1(8) M(2,3) L(5)
1(9) M(3,3) L(6)
1(10) M(I,4)
I( Il) M(2,4)
1(12) M(3,4)
Figura 16.11. Rappresentazione di un bloccoCOMMON non etichettato relativo all'esercizio 16.4.
16.4 Scrivere delle opportune frasi dichiarative che possano essere inserite
nelle unità di programma PRIMA, TERZA, SESTA, NONA in modo tale
da realizzare la spartizione del blocco COMMON non etichettato rappre
sentata in fig. 16.11.
---------- ~--stl----------------
END
330
FUNCfION FUNZ (Y)
DIMENSION Z(3)
COMMON 1BL2 1X(5)EQUIVALENCE (X(2), Y)
l.. 'jJ"
l16.9 Indicare se sono corrette le sequenze di istruzioni qui indicate:
a) COMMON A, B, X( io: d) PROGRAM MAINEQUIVALENCE (B, X( I)) COMMON I BL2 1X(5)
b) COMMON A, B, X(lO)DIMENSION Y(lO)EQUIVALENCE (A, C), (X(5), Y(3))
c) PROGRAM MAIN
COMMON 1BLI 1X(5)
END
,17USO flessibile dei sottoprogrammi
SUBROUTINE SUBCOMMON 1BLI 1X(5)EQUI VALENCE (X(3), Y(3))
END
END
e) SUBROUTINE SUB I
COMMON 1BU 1X(5)
END
FUNCTION FUNZ I (Y)DIMENSION Z(3)
COMMON 1BU 1X(5)EQUIV ALENCE (X (4), Z( I))
END
17.1. Punti di ingresso secondari: l'istruzione ENTRY
L'istruzione ENTRY, non prevista in F66, è una frase non eseguibile che può
essere usata nel corpo di un sottoprogramma per evidenziarne dei punti particolari,
detti punti di ingresso secondari. ciascuno dei quali è identificato da un nome sim
bolico e da una lista di argomenti muti. L'importanza di tali punti è legata al fatto
che un sottoprogramma può essere attivato facendo riferimento al nome di un
punto di ingresso secondario individuato da una frase ENTRY che compare
nel suo corpo. In questo caso lo scambio di informazioni fra l'unità di programma
chiamante e il sottoprogramma avviene tramite la lista di argomenti specificata
per il punto di ingresso secondario e l'esecuzione del sottoprogramrna inizia dalla
frase che segue immediatamente la frase ENTRY (cfr. fig. 17.1).
Figura 17.J. Trasferimento del controUo dell'esecuzione fra unità di programma chiamante esottoprogramma tramite un punto di ingresso secondario.
16.10 Scrivere la frase DATA che definisce come 1.5 il valore iniziale degli ele
menti di un vettore V di lunghezza 15.
16.11 Scrivere la frase DATA che definisce come Ogli elementi della sottomatrice
triangolare superiore di una matrice MAT di 4 righe e 4 colonne.
16.12 Scrivere la frase DATA per predefinire due variabili di tipo carattere dinome TITOLO ed ESEMP con le stringhe 'INIZIALIZZAZIONEvDATI'
e 'TERZOvESEMPIO'.
16.13 Trovare gli eventuali errori nelle seguenti frasi:
a) DAI A I, K, LI 2 * 31b) DATA (V(I), I = K, IO) 1 IO. Il
c) LOGICAL LI
CHARACfER • 4 CARTADATA LI, CARTA /. TRUE., 'FIORI'!
d) REAL REL (2 : 8, - 5 : 5)DATA (REL(I, 1), J = - 5,5), 1= 2, 8) 177. lO
Unità di programma chiamante Sottoprogramma
332
L'istruzione ENTRY ha la forma seguente:
ENTRY nome (m), ... , mn )
dove:
• ENTRY è la parola chiave che identifica la frase;
• nome è un nome simbolico e costituisce il nome del punto di ingresso secondario. Tale nome deve essere diverso dal nome del sottoprogramma in cui la
frase ENTRY compare e dai nomi degli altri eventuali punti di ingresso secondari.
Inoltre esso deve essere diverso dai nomi delle altre unità di programma e dei
loro eventuali punti di ingresso secondari;
• m), ... , mn sono gli argomenti muti del punto di ingresso secondario e possono
avere le forme consentite per gli argomenti muti del sottoprogramma in cui la
frase ENTRY compare.
La lista di argomenti muti in una frase ENTRY può essere diversa da quella
presente nella prima frase del sottoprogramma. Un argomento muto specificato
in una frase ENTRY non può essere usato nelle frasi eseguibili che la precedono,
a meno che esso non sia utilizzato come argomento muto anche in una precedente
frase ENTRY o nella prima frase del sottoprogramma. In ogni caso le frasi dichia
rative relative ai parametri muti di una frase ENTRY devono precedere la prima
frase eseguibile del corpo del sottoprogramma (cfr. appendice A3). Osserviamo a
tale proposito che se la lista di argomenti di una frase ENTRY comprende il nome
di una variabile dimensionata con dimensionamento variabile, essa deve anche
comprendere i nomi delle variabili intere che compaiono nel dichiaratore della va
riabile, a meno che esse non figurino in una frase COMMON. Così, è corretto il
sottoprogramma segue nte:
SUBROUTINE SUB(A, M, V)REAL A(M, e), V(M)
ENTRY PUNTO(V, M)
END
mentre è sbagliato scrivere
SUBROUTINE S(lij(A. M, V)REAL A(M, e), V(M)
ENTRY PUNTO(V)
END
Una frase ENTRY può non prevedere argomenti muti; in questo caso essa può
333
avere una delle forme seguenti:
ENTRY nome ( )
ENTRY nome
Una frase ENTRY può comparire in qualunque punto nel corpo di un sotto
programma, ma non tra una frase IF(c) THEN e la corrispondente frase END IF
oppure tra una frase DO e la corrispondente frase terminale. L'istruzione ENTRY
ha il solo scopo di definire la posizione, il nome e gli argomenti muti di un punto
di ingresso secondario; essa quindi è ignorata se viene incontrata durante l'esecu
zione del sottoprogramma.
Il nome di un punto di ingresso secondario di un sottoprogramma può essere
usato in una unità di programma distinta da questo come argomento attuale in un
riferimento ad un altro sottoprogramma; in questo caso il nome deve comparire
in una frase EXTERNAL nell'unità di programma chiamante. Così è corretta
la situazione seguente nella quale il nome, PUNTO, di un punto di ingresso secon
dario della funzione FUNC viene usato nel riferimento al sottoprogramma SUB
come argomento attuale corrispondente all'argomento muto EFFE:
PROGRAM MAINEXTERNAL PUNTO
CALL SUB(X, PUNTO)
END
SUBROUTINE SUB(X,EFFE)
Y = EFFE(X)
END
REAL FUNCTION FUNC(X\
E~TRY PUNTO(X)
END
r
:\
334
17.2. Punti di ingresso secondari di un sottoprogramma SUBROUTlNE
Il nome di un punto di ingresso secondario di un sottoprogramma di tipo
SUBROUTlNE non può comparire in nessuna frase del sottoprogramma diversa
dalla frase ENTRY che lo definisce.
Esempio 17.1. Date (n + 1) coppie di numeri reali (xi' Yi ) con i = O, l, ... , n
e xi diverso da xj
per i diverso da j, esiste un unico polinomio Pn(x) di grado mi
nore o uguale di n, tale che Pn(xi) = Yi per i = O, l, ... , n. Pn(x) è detto polinomio interpolante le coppie di valori dati e può essere scritto nella forma:
Ao + AI(x - xo) + A2(x - xo)(x - xl) + + An(x - xo) (x - Xl) ... (X - xn- l)
dove Ao è uguale a Yo e i coefficienti Al' , An sono differenze divise calcola-
bili mediante i valori Xi' Yi' i = O, ... , n [9]. Assegnato un valore reale x, il valorep = Pn(x) può essere calcolato utilizzando l'algoritmo seguente:
l. Dati: x; (Xi' Yi) con i = O, l, ..., n;
2. Poni ~ = Yo e Ao = go
3. Per i = l, ... , n
3.1. Poni gi = Yi3.2. Per k = i - l, ..., O
3.2.1. Calcola gk = (gk + l - gk)!(x i - xk)3.3. Poni Ai =~
4. Poni P = An5. Per i = n - l, ..., O
5.1. Calcola P = P' (x - Xi) + Ai6. Risultato: P
7. Stop
Si può osservare che la determinazione dei coefficienti Ao' ..., An è indipen
dente dal valore di x (cfr. istruzioni 2 e 3). Pertanto, quando si voglia calcolare
Pn(X) per più valori di X può essere conveniente eseguire una sola volta le istru
zioni 2 e 3 ed eseguire invece per ogni valore di x le istruzioni 4, 5 e 6. Sulla base
di queste considerazioni si perviene alla scrittura del sottoprogramma POLINT
di seguito riportato. Gli argomenti muti nella prima fase di POLINT hanno il
seguente significato:
- X e Y sono vettori reali che contengono in ingresso i valori xo' ... , xn e Yo' ... ,
Yn rispettivamente;
- N è una variabile intera che contiene in ingresso il valore di n;
- XS è una variabile reale che contiene in ingresso il valore di x;
- A è un vettore reale che contiene in uscita i coefficienti Ao' ... , An;
- PN è una variabile reale che contiene in uscita il valore Pn(x);
- G è un vettore reale di servizio.
335
SUBROUTINE POLINT (X, Y, N, XS, A, PN, G)REAL X(O: N), Y(O : N), A(O : N), XS, PN, G(O : N)INTEGER N
C CALCOLODEI COEFFICIENTI A(O),..., A(N)G(O)= Y(O)A(O) = CIO)DO IO I = l, NG(I) = Y(I)DO 5 K = I - l, O, - IG(K) = (G(K + 1) - G(K» / (X(I) - X(K»)
5 CONTINUEA(I) = G(O)
lO CONTINUEC CALCOLODEL VALORE, PN, DELPOLINOMIO INTERPOLANTEIN XS
ENTRY VALPOL(X,N,XS,A.PN)PN = A(N)DO 15 I = N - l, O,- IPN = PN • (XS - X(I) + A(I)
15 CONTINUERETURNEND
Nel corpo del sottoprogramma figura la frase
ENTRY VALPOL(X,N,XS,A, PN)
che individua un punto di ingresso secondario di nome VALPOL e argomenti
muti X, N, XS, A, PN. Il significato dei parametri X, N, XS, PN è uguale a quello
degli omonimi argomenti presenti nella prima frase del sottoprogramma, mentre
il vettore A in questo caso deve contenere in ingresso i coefficienti Ao' ... , An'
Se il sottoprogramma viene utilizzato in una unità di programma chiamante
nel modo usuale, ovvero facendo riferimento al nome POLINT, la frase ENTRY
viene ignorata durante l'esecuzione e vengono calcolati i coefficienti Ao' ...,
An e il valore Pn(x). Se invece nell'unità chiamante si fa riferimento al nome del
punto di ingresso secondario, VALPOL, allora l'esecuzione del sottoprograrnma
inizia dalla frase che segue la ENTRY; così in questo caso viene calcolato il valore
del polinomio interpolante mentre i coefficienti Ao' ..., An sono assunti comedati in ingresso.
Riferimento ai punti di ingresso secondari di un sottoprogramma SUBROUTlNE
Un riferimento ad un punto di ingresso secondario di un sottoprogramma di
tipo SUBROUTINE è consentito in una unità di programma distinta da questo
ed avviene tramite la frase
CALL nome (al' ... , an )
336
dove:• nome è il nome del punto di ingresso secondario;
• al"'" an sono gli argomenti attuali che devono accordarsi in numero, ordinee tipo con gli argomenti muti del punto di ingresso secondario. Se il punto di ingresso a cui si fa riferimento non prevede argomenti, la frase CALL può avere una
delle forme seguenti:
CALL nome ( )
CALL nome
Al momento dell'attivazione del sottoprogramma i parametri attuali vengono
associati ai parametri muti del punto di ingresso secondario secondo le modalitàviste nel cap. 15 e l'esecuzione del sottoprogramma inizia dalla frase che segue
la ENTRY.
Esempio l 7.2. Sia P4 (x) il polinomio di grado minore o uguale di 4 che interpolacinque coppie di valori reali (Xi' Yi) , con i = O, ...,4, assegnate. Si vuole scrivereun programma che permetta di calcolare e stampare i valori P4 (Xi)' con i = I,· .. , IO, dove i valori xl , ...,xlO sono dati.
Il programma CALPOL che segue, risolve il problema utilizzando il sottoprogramma POLINT dell'esempio precedente. In CALPOL i valori xl' ...,x lO sonomemorizzati nel vettore XS, mentre xo' , x4 e Yo' ..., Y4 sono memorizzatirispettivamente in X e Y e i coefficienti Ao' , A4 in A.
PROGRAM CAlPOLDIMENSION X(5), Y(5), A(5), XS(IO), G(5)DATA N, NXS/4, 101READ-,X, YREAD -. XSCALL POLINT (X, Y, N, XS(I), A, PN, G)PRINT ISO, XS(1), PNDO 20 I = 2, NXSCALL VALPOL (X, N, XS(I), A, PN)PRINT ISO, XS(I), PN
20 CONTINUESTOP
ISO FORMAT (IX, 'PN(, EI3.6, ') =', EI3.6)END
Con la frase
CALL POLINT (x. Y, N, XS(l), A, PN, G)
il sottoprogramma POLINT viene attivato facendo riferimento alla sua frase iniziale. L'esecuzione di POLINT avviene quindi in modo sequenziale ignorando lafrase ENTR Y che fa parte del suo corpo. Al rientro nel programma chiamante
337
sono disponibili in A i valori dei coefficienti Ao' ..., A4 e in PN il valore del po
linomio interpolante in xl'Successivamente, per ogni valore di I compreso fra 2 e lO si esegue la frase
CALL VALPOL (X, N, XS(I), A, PN)
In questo caso si fa riferimento al punto di ingresso secondario del sottoprogramma, e pertanto i parametri attuali X, N, XS(1), A e PN vengono associatiagli argomenti muti X, Y, XS, A e PN specificati nella frase ENTRY nel sotto
programma.. L'esecuzione di POLINT ha inizio in questo caso dalla prima frasesuccessiva alla ENTRY e i valori dei coefficienti Ao' ..., A4 contenuti in A sonoutilizzati come dati in ingresso. Al termine della esecuzione di POLINT il valore del polinomio interpolante in Xi è disponibile in PN.
17.3. Punti di ingresso secondari di un sottoprogramma FUNCTION
Il nome di un punto di ingresso secondario di un sottoprogramma FUNCTIONpuò comparire come nome di variabile in frasi eseguibili successive alla ENTRYche definisce il punto. Il tipo della variabile il cui nome coincide con il nome diun punto di ingresso secondario è detto tipo del punto di ingresso secondario e
può essere specificato mediante la sua lettera iniziale oppure mediante una frase
dichiarativa di tipo che deve precedere la prima frase eseguibile del sottoprogramma (cfr. appendice A3).
Punti di ingresso secondari di tipo carattere
Un punto di ingresso secondario in una funzione esterna di tipo carattere deve
essere di tipo carattere e pertanto il suo nome deve comparire in una fraseCHARACTER che precede la prima frase eseguibile del sottoprogramma. La lunghezza specificata per il nome del punto di ingresso secondario deve essere ugualealla lunghezza della funzione; in particolare essa deve essere espressa medianteuno specificatore di lunghezza indefinita se la funzione ha lunghezza indefinita.
Punti di ingresso secondari di tipo diverso da carattere
In una funzione esterna che non sia di tipo carattere possono essere presentipunti di ingresso secondari di qualunque tipo, ma non di tipo carattere. Di solitotutti i punti di ingresso secondari hanno lo stesso tipo della funzione.
Supponiamo che tutti i punti di ingresso secondari di un sottopogrammaFUNCTION siano dello stesso tipo della funzione; allora durante l'esecuzionedel sottoprogramma il valore della funzione può essere memorizzato in una variabile il cui nome coincide con il nome di un qualunque punto di ingresso secon-
iI
nIIl
'II
1
;II
339338
dari o O con il nome della funzione, qualunque sia il nome usato per l'attivazione.
Da ciò segue che nel corpo del sottoprogramma almeno uno fra i nomi dei puntidi ingresso secondari o della funzione deve essere utilizzato come nome di variabile in frasi eseguibili che ne definiscano il valore. Va comunque tenuto presente
che il nome di un punto di ingresso secondario non può comparire in frasi che
precedono l'istruzione ENTRY che lo definisce, ad eccezione che in una frase
dichiarativa di tipo.
REAL FUNCTION NORMA (U, N)REAL NORMAP, U(N), MAX
C CALCOLO DELLA NORMA INFINITO DI UMAX = ABS(U(I)DO 5 1= 2, NIF (MAX.LT.ABS(U(I))) MAX= ABS(U(I))
5 CONTINUENORMA=MAXRETURN
C
REAL FUNCfION NORMA (U, N)ENTRY NORMAP (U, N, IP)
Esempio 17.3. Se u è un vettore di componenti ul' ... , un' la norma Il u 11_ è de
finita dalla relazione
Si osservi che durante l'esecuzione di un sottoprogramma FUNCnON tutti inomi di variabile dello stesso tipo che vengono usati nel corpo del sottoprograrn
ma e che coincidono con il nome della funzione o con il nome di un punto di
ingresso secondario identificano la stessa locazione di memoria.
Supponiamo ora che in una funzione esterna siano definiti dei punti di ingres
so secondari il cui tipo non coincide con il tipo della funzione. In questo casoil risultato di ogni esecuzione del sottoprogramma deve essere un valore dellostesso tipo del nome .tramite il quale è avvenuta l'attil'azione. Il risultato deve
quindi essere memorizzato in una variabile del tipo suddetto il cui nome coincide
con il nome di un punto di ingresso secondario oppure con il nome della funzione.Inoltre, durante l'esecuzione non deve essere assegnato alcun valore a variabili
di tipo diverso dal nome tramite il quale è avvenuta l'attivazione e il cui nome
coincida con il nome di un punto di ingresso secondario oppure con il nome
della funzione.
ENTRY NORMAP(U, N, IP)C CALCOLO DELLA NORMA-P DI U
MAX = ABS(U(1)DO lO 1= 2, NIF (MAX.LT.ABS(U(I)) MAX= ABS(U(I))
lO CONTINUENORMAP=O.IF (MAX.EQ.O.) RETURN00151=I,NNORMAP= NORMAP+ (U(I)/MAX) •• IP
15 CONTINUENORMAP= MAX. NORMAP.. (1./IP)END
In questo sottoprogramma il nome della funzione, NORMA, e il nome delpunto di ingresso secondario, NORMAP, sono entrambi di tipo reale. Pertanto
il significato del sottoprogramma resta inalterato se nelle frasi che seguono l'istruzione ENTRY si sostituisce il nome NORMAP con il nome NORMA. Sarebbe
invece sbagliato sostituire NORMA con NORMAP nelle frasi eseguibili che precedono la ENTRY.
altrimenti.
max lUi Ii c iO:; nIlull_=
Data Il u 11_ ' è possibile calcolare la norma ~ u Il p con p intero positivo, nel modo
seguente:
Il seguente sottoprogramma NORMA può essere utilizzato ner calcolare Il u 11oppure Il u 1\ con p > O assegnato. Nel primo caso il sottoprogramrna deve
essere attivafo mediante il nome, NORMA. che compare nella prima frase, mentre
nel secondo caso deve essere attivato mediante il nome, NORMAP, del suo punto
di ingresso secondario. Gli argomenti muti U ed N nelle due frasi
rappresentano rispettivamente il vettore u di cui si deve calcolare la norma e la sua
dimensione n; l'argomento muto IP nella frase ENTRY contiene in ingresso il
valore di p.
l !
340
Riferimento a punti di ingresso secondari di una funzione esterna
Un riferimento ad un punto di ingresso secondario di una funzione esterna
è consentito in unità di programma distinte dalla funzione ed ha la forma se
guente:
dove:• nome è il nome del punto di ingresso secondario;• al"'" a
nsono gli argomenti attuali che devono accordarsi in numero, ordine e
tipo con gli argomenti muti del punto di ingresso secondario. Se il punto d'in
gresso secondario non prevede argomenti, il riferimento deve avere la forma
nome ( )
L'attivazione e l'esecuzione del sottoprogramma avvengono nel modo già descritto
nel paragrafo precedente per i sottoprogrammi SUBROUTINE.
Esempio 17.4. II seguente programma utilizza la funzione NORMA dell'esempioprecedente per calcolare IleO)1.. ,~cO) Il eleO) b, con i = l, ... , n, dove c(i)
indica l'i-esima colonna di una matrice reale C di ordine n = lO.
REAL NORMA, NORMAPPARAMETER (N = IO)DlMENSION C(N, N)READ .,CDOI5I=I,NCN = NORMA (C(1. I), N)CNI = NORMAP (C(l, I), N,I)CN2 = NORMAP(C(l, I), N, 2)WRITE (.,35) I, CN, CNI, CN2
15 CONTINUESTOP
35 FORMAT (IX, 'COLONNA N.', I2/IX, 'NORMA INFINITO:', EI3.6/• IX, 'NORMA-l:', Ell 6/IX, 'NORMA-2:', EI3.6)
END
Per effetto del riferimento NORMA(C( l, I), N) gli argomenti attuali C( l, I)
ed N vengono associati alli argomenti muti della prima frase del sottoprogramrna
REAL FUNCfION NORMA (U, N)
L'esecuzione del sottoprogramma procede quindi in modo sequenziale e ter
mina quando viene eseguita l'istruzione RETURN che precede la frase
ENTRY NORMAP (U, N, IP)
341
Quando il sottoprogramma viene attivato mediante uno dei riferimentiNORMAP (C( l, I), N, l) e NORMAP (CO, I), N, 2), gli argomenti attuali vengo
no associati a quelli muti della frase ENTRY e vengono quindi eseguite tutte leistruzioni che seguono questa frase. Si osservi che nel programma chiamante è
indispensabile la frase di specificazione
REAL NORMA, NORMAP
Dagli esempi svolti in questo e nel precedente paragrafo, possiamo concludere
che l'istruzione ENTR Y è uno strumento utile in due tipi di situazioni: quando in
un sottoprogramma si individua un blocco di istruzioni che seguono la prima frase
e che in alcune particolari utilizzazioni del sottoprogramma non devono essere
eseguite (cfr. esempio 17.1), oppure quando il corpo di un sottoprogramma è
costituito da due o più blocchi uno solo dei quali viene eseguito ad ogni attiva
zione del sottoprogramma (cfr. esempio 17.3). Nel seguito del capitolo vedremo
altre situazioni in cui l'istruzione ENTRY può essere vantaggiosamente utilizzata.
17.4. Le variabili interne di un sottoprogramma e l'istruzione SAVE
NelIe istruzioni che compongono il corpo di un sottoprogramma si utilizzano
spesso nomi simbolici che identificano variabili interne o locali al sottoprogramma, ovvero variabili il cui contenuto non è oggetto di scambio di informazionicon l'unità di programma chiamante. Più precisamente, le variabili interne sono
tutte quelle variabili i cui nomi non compaiono come argomenti muti nella primafrase del sottoprogramma o in qualche frase ENTRY e che non fanno parte di un
blocco COMMON. Durante l'esecuzione del sottoprogramma i nomi delle varia
bili interne identificano delle locazioni di memoria il cui contenuto può essere
definito ed utilizzato dal sottoprogramma stesso. II periodo di tempo durante il
quale il nome di una variabile interna identifica una particolare zona di memoria
è limitato al tempo che intercorre fra l'attivazione del sottoprogramma e il rientro
nell'unità di programma chiamante. Pertanto se un sottoprogramma viene utiliz
zato più volte durante l'esecuzione del programma, non vi è alcuna garanzia che
il valore delIe sue variabili locali resti inalterato da una chiamata all'altra. Se si
desidera che ciò avvenga per alcune variabili interne, occorre specificare i loro no
mi in una frase dichiarativa SAVE nel corpo del sottoprogramma. In questo casol'istruzione SAVE può' avere la forma seguente:
SAVE v}' ... , vn
dove:• SAVE è la parola chiave che identifica la frase;
• v}' ... , vn sono i nomi delle variabili interne, dimensionate e non dirnen-
IlII
11
________________--..+--------..-------------1
342
sionate, di cui si vuole che sia mantenuto il valore al termine dell'esecuzione del
sottoprogramma.
Esempio 17.5. Sia dato un problema ai valori iniziali per un sistema di equazioni
differenziali ordinarie nella forma
\ y'(t) = f(t, y(t))
l y(to) = Yo
dove y(t), per ogni t nell'intervallo [to' te], è un vettore di ]R." e f(t, y(t)) è una
funzione a valori in JR" tale che il problema ammette un'unica soluzione y(t).
Esistono molti metodi numerici che consentono di approssimare i valori y(t j )
che la soluzione assume su un insieme di punti ti' con i = l, ... , N, dove
to
< ti < ... < tN = te (cfr. [9] e [lO)). Il sottoprogramma RK:S, la. cui listacompleta si trova in [lO], utilizza un particolare metodo numenco (di Runge
Kutta-Fehlberg) per calcolare un vettore u j che approssima y(t j ) avendo come
dato un vettore ui_ I che approssima y(ti_ 1) · Posto Uo = Yo assegnato, il sotto
programma deve essere richiamato N volte consecutive per calcolare ul' ... , uN'
SUBROUTINE RKFS (F, NEQN, Y, T, TOUT, RELERR, ABSERR,• IFLAG, yP, H, Fl, F2, F3, F4, F5, SAVRE, SAVAE, NFE, KOP. INIT,
• JFLAG, KFLAG)
MFLAG = IABS (IFLAG)
IF (MFLAG.NE.l) GOTO 20C PRIMA CHIAMATA - SI CALCOLANO EPS E U26
EPS = 1.0EPS = EPS/2.0EPSPI = EPS + 1.0IF (EPSl.GT.l.) GOTO 5026 = 26.0 • EPSGOTO 50
C CHIAMATE SUCCESSIVE20 CONTINUE
50 CONTINUE
RER = 2.• EPS + REMIN
HMIN = 026 • ABS (T)
END
343
Fra gli argomenti muti di RKFS, il significato dei quali è spiegato in [lO],
Y è un vettore che contiene in ingresso ui_ I e in uscita uj' mentre T e TOUT
contengono in ingresso ti_ I e ti rispettivamente. Inoltre IFLAG è un indicatoreche può assumere in ingresso e in uscita diversi valori; in particolare alla prima
chiamata di RKFS il valore assoluto di IFLAG in ingresso deve essere uguale a
l, mentre deve essere diverso da l alle chiamate successive. Osserviamo che nelcorpo del sottoprogramma vengono utilizzate due variabili locali, EPS e U26,
i cui valori vengono calcolati una volta per tutte alla prima chiamata. Evidente
mente, RKFS può fornire risultati corretti alle chiamate successive alla prima sol
tanto se il sistema di calcolo con cui si lavora mantiene inalterato il valore delle
variabili interne anche dopo il rientro nella unità di programma chiamante. Per
avere la garanzia che questo succeda per qualunque sistema di calcolo occorre
inserire tra le frasi dichiarative del sottoprogramma l'istruzione seguente:
SAVE EPS, U26
Esempio 17.6. Consideriamo il seguente sottoprogramma:
SUBROUTlNE PARAM (ALFA)SAVE AA=ALFARETURNENTRY FALFA (X, Y)Y = 0.5. (EXP(ALFA. X) - EXP(- ALFA. X))RETIJRNEND
L'attivazione di questo sottoprogramma mediante la prima frase consente di
memorizzare nella variabile locale A il valore dell'argomento attuale corrisponden
te all'argomento muto ALFA; essendo presente la frase SAVE A, tale valore viene
conservato anche dopo il rientro nell'unità di programma chiamante. Così il valo
re di ALFA è disponibile per l'esecuzione del sottoprogramma se questo viene
successivamente attivato tramite il punto di ingresso secondario definito dallafrase
ENTRY FALFA (X, Y)
Un esempio di utilizzazione del sottoprogramma PARAM è tratteggiato quidi seguito:
344
PROG RAM MAINEXTERNAL FALFA
A=O.lCALL PARAM (A)CALL SUB (FALFA, ...)
END
SUBROUTINE SUB (F, ...)
CALL F(X, Y)
END
Il programma principale attiva il sottoprogramma PARAM in modo che venga
memorizzato nella variabile locale A il valore 0.1; successivamente il sottopro
gramma SUB richiama il sottoprogramma PARAM mediante il nome del puntodi ingresso secondario FALFA.
Esempio 1 7. 7. E' noto che una funzione ricorsiva può essere tradotta in un sottoprogramma che fa uso di cicli-DO e di particolari strutture di dati dette pile [15].
Una pila è un insieme ordinato di elementi sul quale sono consentite le seguentioperazioni:
a) aggiungere un elemento in testa alla pila;
b) prelevare un elemento dalla testa della pila.
Per dare un'idea, necessariamente semplificata, di come può essere costruito
un sottoprogramma non ricorsivo come risultato della traduzione di una funzione
ricorsiva, consideriamo la funzione min, definita neli' esempio 1.13, che calcola
l'elemento minimo di un vettore. Ricordando che, indicato con [al' ... , an] il
vettore dato, se ne possono evidenziare il primo e i restanti elementi usando la
notazione [al Iz] con z = [a2, ..., an] (cfr. esempio 1.11), la definizione dellafunzione min è la seguente:
min ([al)) = al
min ([al' a2 )) = se al < ~ al/ora al altrimenti a2
min ([ali z)) = min ([al' min (z)))
In questo caso gli elementi della pila sono gli indici degli elementi del vettore
a = [al' ... , an]· Il sottoprogramma non ricorsivo prevede due fasi. Nella primafase si provvede a definire gli elementi della pila, simulando in questo modo lechiamate della funzione min presenti nella parte ricorsiva della definizione; in-
345
fatti da questa si ottiene che
min ([ali z l) = min ([al' min ([a 2, min ([a 3, .•.»])
Nella seconda fase si utilizza la parte non ricorsiva della definizione per calcolare
il valore della funzione. Ciò avviene nel modo seguente: vengono prelevati dallapila l'elemento in testa e quello immediatamente precedente e vengono confron
tati fra loro gli elementi del vettore ad essi corrispondenti; l'indice del minimo
fra questi due elementi viene quindi aggiunto alla pila e diventa il nuovo elemento
di testa. Si procede così finché la pila non contiene un solo indice che necessa
riamente è quello dell'elemento minimo cercato.Per realizzare le operazioni sopra tratteggiate si utilizzano due sottoprogrammi:
la funzione esterna MIN l che calcola il minimo e il sottoprogramma AGG, di tipo
SUBROUTINE utilizzato dalla prima per eseguire le operazioni sulla pila. I due
sottoprogrammi possono essere utilizzati per calcolare min ([al' ... , an j) con
l ~ n ~ 100.
SUBROUTINE AGG(K)INTEGER PILA (100), TESTASAVE PILA, TESTADATA TESTA /0/
C AGGIUNT A DI UN ELEMENTO IN TEST A ALLA PILAIF (TESTA.GE.lOO) THEN
PRINT -. 'LA PILA Eli PIENA'STOP
ELSETESTA = TESTA + lPILA (TEST A) = KRETURN
ENDIFC PRELIEVO DELL'ELEMENTO IN TEST A ALLA PILA
ENTRY PREL (K)IF (TESTA.LT.I) THEN
PRINT -. 'LA PILA Eli VUOTA'STOP
ELSEK = PILA (TESTA)TESTA = TESTA - lRETURN
ENDIFEND
L'argomento muto K nella prima frase del sottoprogramma contiene in ingres
so il valore che deve essere aggiunto in testa alla pila, mentre nella frase
ENTRY PREL (K)
esso contiene in uscita il valore che è memorizzato nell'elemento in testa alla pila.
Ii
1 I:1
l
______________-...-__.....--rrtL-------------------.
----------------- -
346
II vettore intero PILA che contiene la pila e la variabile intera TEST A che contiene la posizione in PILA dell'elemento di testa sono variabili locali il cui valore viene conservato da una chiamata all'altra per effetto delIa presenza della frase
SAVE PILA, TESTA
II valore di TESTA viene aggiornato ad ogni chiamata del sottoprogramma. Inparticolare, se questo viene attivato tramite la prima frase, il valore di TEST A vie
ne incrementato di una unità e viene posto uguale a K il valore di PILA (TESTA);se invece il sottoprogramma viene attivato tramite il punto di ingresso secondario PREL, il valore di PILA (TESTA) viene assegnato al parametro di uscitaK e successivamente il valore di TESTA viene decrementato di una unità.
La funzione esterna MIN1 utilizza il sottoprogramma AGG per calcolare ilminimo fra i primi N elementi di un vettore A di 100 elementi.
REAL FUNCTION MINI (A, N)REAL A(lOO)
C PRIMA FASE; SI MEMORIZZANO NELLAPILA GLI INDICI I, ... , NDO IO I = I, NCALL AGG(I)
IO CONTINUEIF (N.EQ.I) GOTO 30
C SECONDA FASE: SI RIPERCORRE LA PILA ALL'INDIETRODO 20 I = N, 2, - I
C GLI ELEMENTI DI A CORRISPONDENTI AI DUE ELEMENTI DIC TESTA DELLA PILA VENGONO CONFRONTATI. L'INDICE DELC PIU' PICCOLO FRA I DUE DIVENTALA NUOVA TESTA DELLA PILA
CALL PREL (KI)CALL PREL (K2)IF (A{KI).LT.A(K2» THEN
CALL AGG(KI)ELSE
CALL AGG(K2)ENDIF
20 CONTINUEC LA PILA CONTIENE L'INDICE DELL'ELEMENTO MINIMO DI AC LA SECONDA FASE HA TERMINE
30 CONTINUECALL PREL (K)MINI = A(K)RETURNEND
Ricordiamo che una variabile interna ad un sottoprogramma predefinita mediante una frase DATA conserva il suo valore per la durata dell'esecuzione dell'intero programma, soltanto se questo valore non viene modificato nel sottoprogramma. In caso contrario, affinché il valore venga mantenuto fra due successive
347
chiamate del sottoprogramma, è necessario che il nome della variabile figuri in
una frase SAVE nel corpo del sottoprogramma.
17.5. I blocchi COMMON etichettati e l'istruzione SAVE
Una situazione analoga a quella descritta nel paragrafo precedente per le variabili interne ad un sottoprogramma, si verifica anche per i blocchi COMMONetichettati. Più precisamente, quando termina l'esecuzione di un sottoprogrammache ha accesso ad un blocco COMMON etichettato i valori memorizzati nelblocco vengono conservati soltanto se allo stesso blocco ha accesso anche l'unitàchiamante oppure un'altra unità che, attraverso una catena di chiamate, ha provocato l'attivazione del sottoprogramma. In caso contrario non si ha la garanziache i valori memorizzati nel blocco vengano conservati, e si dice che il blocco diventa indefinito. Evidentemente, un blocco COMMON presente anche nel programma principale non diventa mai indefinito nel corso dell'esecuzione del programma. Inoltre non diventa mai indefinito il blocco COMMON non etichettato.
Esempio 17.8. In un programma costituito dal programma principale MAIN e daiquattro sottoprogrammi SUB l, SUB2, SUB3, SUB4, sono definiti tre blocchiCOMMON etichettati di nomi ETMI24, ETI3, ET34. Supponiamo che I'organizzazione del programma possa essere schematizzata nell'albero delle chiamate difig. 17.2, dove in ogni rettangolo si sono riportati, oltre al nome dell'unità di
programma, i nomi dei blocchi COMMON a cui essa può accedere. Dalla figura
possiamo dedurre quanto segue:
Figura 17.2. Albero deUe chiamate e accesso ai blocchi COMMON nell'esempio 17.8.
348
- II blocco COMMON/ETM 124/ non diventa mai indefinito dal momento che è
utilizzato nel programma principale;
- II blocco COMMON/ET 13/ non diventa indefinito al termine della esecuzionedi SUB3; infatti a questo blocco ha accesso anche il sottoprogramma SUB l che,avendo richiamato SUB2, ha provocato l'attivazione di SUB3. Pertanto i valorimemorizzati nel blocco vengono conservati quando termina l'esecuzione di SUB3e il blocco diventa indefinito soltanto al termine dell'esecuzione di SUB l, quando
il controllo ritorna al programma principale;
- II blocco COMMON/ET34/ diventa indefinito sia al termine della esecuzione di
SUB3 che al termine dell'esecuzione di SUB4. Evidentemente in questo caso non
vi è più la garanzia che le informazioni memorizzate nel blocco da uno dei duesottoprogrammi vengano ritrovate intatte dall'altro; ciò può comportare una to
tale perdita di significato del blocco se questo viene utilizzato come mezzo per
la trasmissione di informazioni fra i due sottoprogrammi.
Situazioni come quella ora descritta possono essere evitate dichiarando nel pro
gramma principale tutti i blocchi COMMON etichettati che vengono utilizzati dal
le varie unità di programma. In F77 si può usare allo stesso fine l'istruzione SAVE
la cui forma generale è infatti la seguente:
SAVE lista
dove ogni elemento della lista può essere il nome di una variabile interna oppure il
nome di un blocco COMMON racchiuso fra sbarre e due successivi elementi dellalista sono separati mediante una virgola.
Se il nome di un blocco COMMON figura in un'istruzione SAVE in una unitàdi programma, le variabili del blocco conservano il loro valore al termine dell'esecuzione di questa unità. Così, per esempio, l'istruzione
SAVE A, B, /COMC/, K l
serve a specificare che le variabili interne A, B e K l e le variabili facenti parte del
blocco COMMON/COMC/ devono mantenere il loro valore anche dopo la fine
dell'esecuzione del sottoprogramma in cui la frase compare. Notiamo che se il
nome di un blocco COMMON fa parte della lista di un'istruzione SAVE in una
unità di programma, esso deve figurare in un'istruzione SAVE anche in tutte le
altre unità di programma che hanno accesso al blocco.
L'istruzione SAVE in un sottoprogramma può anche ridursi alla sola parola
chiave
SAVE
In questo caso tutte le variabili interne e le variabili di tutti i blocchi COMMONetichettati a cui il sottoprogramma ha accesso mantengono il loro valore al termine dell'esecuzione del sottoprogramma.
349
Esercizi
17.1 Individuare gli errori presenti nei seguenti sottoprogrammi:a) SUBROUTINE MAT (A, NMAX, N)
REAL A (NMAX, N)
ENTRY SUBMAT(A, N)
END
b) SUBROUTINE SUB (A, B, C)
D=l.
ENTRY SUBS (D)
END
c) FUNCTION FUNZ (X, Y)
A = DER (X, Y)
ENTRY DER (X, Y)
END
17.2 Modificare il sottoprogramma POLINT dell'esempio 17.1 in modo tale daottenere un nuovo sottoprogramma che non faccia uso dell'istruzione ENTRY
e che, come POLINT, possa essere utilizzato per calcolare i coefficienti
Ao' ..., An del polinomio interpolante e il valore Pn(x) oppure solo per calcolare Pn(x). (suggerimento: inserire un indicatore fra gli argomenti muti).
17.3 Modificare, nello stesso spirito del precedente esercizio, il sottoprogrammaNORMA dell'esempio 17.3.
17.4 Scrivere, facendo uso dell'istruzione ENTR Y, un sottoprogramma che possa
essere usato per calcolare, assegnato un valore di x, il valore della funzionefl x) definita da:
f(x) = x - sen (x - l) - l
oppure il valore della derivata ['(x), definita da
f'(x) = l - cos (x - l)
I.
k = O, l, ...,4.
350
17.5 Scrivere, facendo uso dell'istruzione ENTRY, un sottoprogramma mediante
il quale si possa calcolare, dato x, il valore di f(x) oppure i valori di f(x) e
f''(x), dove f(x) è la stessa funzione del precedente esercizio.
17.6 Scrivere un programma che, utilizzando il sottoprogramma dell'esercizio
17.4, permetta di calcolare e stampare i valori di f(x i ) e f'(x i) per Xi == 0.5 + i 0.01, i = O, ..., lO.
17.7 Scrivere un programma che, utilizzando il sottoprogramma dell'esercizio
17.5, permetta di calcolare e stampare i primi cinque termini della succes
sione {xk }, dove Xo = O e i restanti termini sono definiti da
f(xk
)
x =x ---k+l k f'(x
k)
II programma deve interrompersi se, per un valore di k, risulta r'(xk) = O.
17.8 II sottoprogramma PARAM dell'esempio 17.6 deve necessariamente esseredi tipo SUBROUTINE e non può essere di tipo FUNCfION. Spiegare il
motivo di tale affermazione.
17.9 Spiegare il significato che assume il sottoprogramma PARAM dell'esempio
17.6 se si elimina dal suo corpo la frase RETURN che precede l'istruzione
ENTRY. Scrivere un programma principale che utilizzi il sottoprogramma
PARAM nella versione così modificata per calcolare i valori della funzione
y = 0.5 (eQ X - e(- QX)
con Cl' = 0.01 per i seguenti valori di x: O, 1, 2, 3, 4.
"
18Trattamento dei files
18.1. Introduzione
Abbiamo fin qui trattato le operazioni di I/O procedendo dalla loro formapiù semplice, le frasi di I/O guidate dalla lista (cfr. cap. 8), fino ad una formaun po' più complessa, le frasi di I/O con formato (cfr. cap. 13).
Tali argomenti non esauriscono l'esposizione del complesso delle istruzioniche il F77 offre all'utente per una completa e sofisticata gestione del meccanismodi I/O.
In generale una operazione di I/O comporta la trasmissione di informazionisotto forma di records da o verso unità (o mezzi) di I/O cui sono associati deifiles. Tale trasmissione può avvenire sotto il controllo di formato (cfr. cap. 13)oppure senza il controllo di formato. Ancora, la modalità di accesso ad un filepuò essere sequenziale o diretta.
Inoltre, tali files possono essere rappresentati su supporti esterni alla memoriacentrale, ad esempio su una stampante o video, su nastro o disco magnetico, oall'interno della memoria centrale.
Da quanto detto si vede quanto possano essere diversificate le operazioni di
I/O a seconda delle necessità e, conseguentemente, quante informazioni debbano
essere fornite prima di un'operazione di I/O per stabilire le varie caratteristichedel file associato all'unità usata nell'operazione stessa.
Una operazione di I/O può poi svolgersi senza alcun errore oppure no: può
essere allora utile gestire in qualche modo queste eventualità. Vedremo che la
forma generale delle istruzioni di I/O prevede anche tali possibilità.
18.2. Records e files
Nel cap. 13 abbiamo esaminato le varie possibilità disponibili in F77 per realizzare le richieste dell'utente che voglia fornire dati e vedere i risultati dell'ese
cuzione di un certo programma avendo in mente la gestione dei mezzi di I/O chetrasmettono informazioni strutturate sotto forma di files di tipo sequenziale i
352
cui records sono costituiti da sequenze di caratteri con una prestabilita confi
gurazione: i records con formato.Una prima definizione di records e files è già stata data nel cap. 13. Conviene
qui riprendere questi concetti per poter descrivere le rimanenti possibilità per
la gestione di operazioni di I/O «meno intuitive» di quelle già viste.I records previsti in F77 sono di tre tipi:
a) records con formato, costituiti da sequenze di caratteri riconosciuti dal siste
ma di calcolo;b) records senza formato, costituiti da sequenze di valori, nella forma di rappre
sentazione interna;c) record endfile.
Nel cap. 13 abbiamo solo trattato i records di tipo a).
.Lìna sequenza di records tutti del medesimo tipo (a) o b» costituisce un file.
A loro volta, i files possono essere suddivisi in due categorie:
a) files esterni, rappresentati su supporti esterni alla memoria centrale dell'ela
boratore;b) files interni, rappresentati all'interno della memoria centrale; sono usati
esclusivamente quale magazzino temporaneo di dati, la loro «vita» è quella del
tempo di esecuzione del programma in cui sono definiti come vedremo nel se
guito.
Per quanto riguarda i files esterni, rappresentati su supporti magnetici, nastri
e dischi, occorre mettere in luce una profonda differenza fra i due tipi di suppor
to magnetico.Il nas!ro magnetico è un supporto seque,!zitl/~, come lo sono una stampante,
una telescrivente, un video o un lettore di schede. Ciò implica che per accedere
ad un record del file occorre avere prima scorso tutti i records che si trovano pri
ma di quello voluto; in altri termini, i records devono essere letti nel medesimo
ordine in cui sono stati scritti. Tale caratteristica comporta un certo dispendio
di tempo per lo scorrimento, avanti o indietro, del nastro per poter accedere al
record voluto.Su di un disco, al contrario, si può accedere ad ogni sua parte in un tempo
estremamente inferiore a quello necessario sul nastro: come vedremo più avantioccorre solo che la testina di lettura/scrittura si sposti di qualche centimetroavanti o indietro per posizionarsi sulla parte voluta.
Si dice allora che su tale mezzo le informazioni possono essere reperite ad
f!.c:..E~sso c!ire!to, per significare la differenza con il concetto di accesso sequenziale
visto sopra. Tale caratteristica del disco non impedisce che su di esso si possano
gestire files anche in modo sequenziale, mentre il viceversa non è possibile sui
nastri: questi consentono solo un accesso sequenziale.
353
Conseguentemente, i files possono essere files sequenziali o files ad accesso
diretto.Volendo allora leggere o scrivere informazioni su di un file esterno dovremo
specificare quale sia il modo di accesso al file, sequenziale o diretto, e se i suoi
records sono con o senza formato.Tali specifiche, insieme a diverse altre, vengono esplicitamente fomite tramite
la frase .~~Ia cui utilizzazione non è richiesta per alcuni mezzi esterni, adesempio i mezzi standard, per i quali il sistema assume implicitamente il modo di
accesso sequenziale e records con formato.
Records con formato e senza formato
I records con formato sono costituiti da una sequenza di caratteri tale da essere
facilmente compresa da un essere umano. Tali records sono scritti tramite le operazioni di uscita guidate dalla lista o sotto il controllo esplicito del formato.
Ancora, questi records possono anche essere creati senza l'esecuzione di un programma FORTRAN, ad esempio servendosi di programmi di «editing» general- I
mente disponibili nei moderni sistemi di calcolo.La lunghezza di un record con formato è data dal numero di caratteri che lo
compongono. Si noti che la conoscenza della lunghezza di un record è necessaria
quando il file cui il record appartiene sia dichiarato ad accesso diretto.
La trasmissione di un record con formato implica una conversione da rappre
sentazione esterna ad interna o viceversa dei dati in esso contenuti; ciò compor
ta un tempo non trascurabile. Se, d'altra parte, l'informazione scritta sul record
non deve essere letta da un essere umano, ma successivamente letta nel medesimo
o altro programma, non si presenta la necessità di dover convertire questa infor
mazione da rappresentazione interna ad esterna o viceversa.
l/In questo caso, con grande risparmio di tempo, basta usare frasi di I/O senza il/'I controllo di formato per produrre o leggere records senza formato.
I Un record senza formato è costituito da una sequenza di valori rappresentati
~econdo modalità dipendenti dal sistema. In generale un valore è esattamente
111a rappresentazione interna di un dato; così un record senza formato può esseriiconsiderato la copia di una parte della memoria.
Frasi di I/O senza formato possono essere scritte semplicemente non riportando
l'identificatore di formato, ma solamente il riferimento all'unità di I/O come si
vede nelle frasi seguenti:
WRITE (8) A V, BV, CV
READ (9) X, Y
La prima fa sì che venga scritto il record costituito dai valori attuali delle varia
bili AV, BV e CV sul file associato all'unità 8; la seconda ha invece l'effetto di
, II
354
leggere, dal file associato all'unità 9, un record che si suppone costituito da due
valori che, senza alcuna conversione, sono assegnati alle variabili X e Y.La lunghezza di un record senza formato è misurata in unità dipendenti dal
sistema; generalmente l'unità di misura è il byte o multiplo di byte. Così se ivalori di AV, BV e CV sono rappresentati su quattro by tes, il record prodottodalla frase WRITE sopra riportata risulta lungo 12 bytes.
Notiamo una importante differenza fra le frasi di I/O con formato e quellesenza.
Le prime, per effetto del controllo congiunto fra lista e specificazione di for- I
',mato, possono trasmettere più records; le seconde possono trasmettere un solo
((I(' \" record per volta.III Inoltre, la lunghezza della lista in una istruzione d'ingresso senza formato deve
Il;! iessere minore o uguale alla lunghezza della lista della frase di uscita che ha pro-
,'l'dotto il record che sta per essere letto.
Esempio 18.1. Affinché la frase
READ (9) X, Y
possa essere correttamente eseguita occorre che il record che sta per essere letto
sul file associato all'unità 9 sia costituito da almeno due valori.
Nel caso in cui la lunghezza della lista sia inferiore a quella del record che sta
per essere letto, i valori eccedenti sul record resteranno non letti.
Il record endfile e la frase ENDFILE
Il record endfile può essere posto solo come ultimo record di un file ed è prodotto con l'uso della frase speciale:
355
Il significato di questi specificatori verrà dato nel paragrafo successivo.
Notiamo che, comunque, l'unità riferita da u deve essere ad accesso sequen- , ! I
ziale. I
L'effetto principale dell'esecuzione della frase ENDFILE è quello di scrivere
sul file associato all'unità u il record speciale endfile. Ciò rende impossibile ogni
successivo tentativo di leggere da o scrivere su quel file senza avere prima scorsoall'indietro il file usando una frase BACKSPACE o REWIND (cfr. § 18.5).
E' molto comodo porre tale record alla fine di files sequenziali che devono essere successivamente riletti per facilitare tale rilettura completa senza dover con
trollare la lunghezza del file da leggere. L'uso del record endfile verrà evidenziatonell'esempio 18.12.
18.3. La forma generale delle frasi di I/O
La forma generale delle frasi di I/O è la seguente:
rw (dista) lista-di-I/O
dove:
• rw è la opportuna parola chiave: READ per le operazioni di ingresso,WRITE per quelle di uscita;
• lista-di-I/O è la lista degli elementi i cui valori devono essere trasmessi; per lasua forma cfr. cap. 13;
• dista è la lista di controllo che fornisce informazioni sia circa l'unità diI/O che sulla natura e modalità di gestione dell'operazione.
L'effetto principale di un 'operazione di I/O è quello già ampiamente descrittonel cap. 13: la trasmissione di uno o piu records.
La lista di controllo
Tale lista è costituita dall'elenco di tutti o parte dei seguenti specificatori separati da virgole
I
l",l, \
ENDFILE u
oppure
ENDFILE (auxlista).
Nella prima forma u è l'espressione intera il cui valore denota il numero dell'u
nità sulla quale il record deve essere scritto; nella seconda forma la lista auxlista
può contenere ciascuno dei seguenti specificatori separati da virgole e senz'altrolo specificatore relativo all'unità:
u
UNIT = uERR =s10STAT = v
gli specificatori u e UNIT = u sono equivalenti.
u
UNIT = uf
FMT= f
10STAT = sERR =sEND =sREC = n
Lo specificatore u oppure UNIT u, relativo all'unità di I/O, deve essere
356
sempre presente. In particolare, se esso è l'unico specificatore presente, la frase
in questione rappresenta una operazione di l/O senza formato sul file (sequenzia
le) associato all'unità specificata.
Se la stringa UNlT = è omessa, allora lo specificatore u deve essere il primo elemento della lista di controllo. Lo specificatore u può avere una delle forme se
guenti:
a} un'espressione intera il cui valore identifica l'unità di l/O interessata all'o
perazione e quindi il file ad essa associato;
b) il carattere asterisco ... che denota l'opportuno mezzo standard;
c) uno dei seguenti elementi di tipo carattere: una variabile, un elemento di
variabile dimensionata, una sottostringa, una variabile dimensionata.
La specifica dell'unità secondo le forme a) e b) consente di gestire files esterni.Quella -~econdo la forma c) consente la gestione di files interni; le operazioni di
17C>;~iative a queste unità verranno descritte nel § 18.8.
In una operazione di l/O con formato deve essere presente uno dei seguenti( specificatori:
FMT = f oppure f
ILa stringa FMT = può essere omessa solo se è stata omessa la stringa UNlT =
nello specificatore d'unità, in questo caso l'identificatore di formato f dev~ essereil secondo elemento nella lista di controllo.
Si noti che se lo specificatore di formato è assente l'operazione di l/O avvienesenza il controllo di formato.
Esempio 18.2. Alcune frasi di l/O fra loro equivalenti:
READ (UNII = l, FMT = 50) A, B, CREAD (FMT = 50, UNII = l) A, B, CREAD (1, FMT = 50) A, B, CREAD (l,50) A, B, CREAD (I, 50) A, B, CREAD (l, '(3FlO.0)') A, B, CREAD (UNII = l, FMT = '(3FlO.0)') A, B, C
50 FORMAT (3FIO.0)
357
Si noti che fra tutte le forme di frasi di I/O dell'esempio 18.2 soloREAD( l ,50) A, B, C REA D (I, 50) A, B, C WRlTE (2, 60) A, B, C eWRlTE (J, 60) A, B, C sono consentite in F66.
Gli specificatori di
stato 10STAT = v
errore ERR = s
fine file END = s
sono opzionali e, se presenti, le relative parole chiave devono essere pureriportate.
Nello specificatore di stato 10STAT = v, v è un nome di variabile o elementodi variabile dimensionata di tipo intero. AI termine dell'operazione di l/O v assumeun determinato valore:
• zero, se l'operazione ha avuto termine normalmente;
• un intero positivo, se è occorso un errore, ad esempio di conversione di un
dato, oppure se il file associato all'unità specificata non ha opportune caratteristiche: è costituito ad esempio da records senza formato mentre l'operazione ècon formato;
• un intero negativo, se l'operazione in questione è un'operazione di ingresso ditipo sequenziale, nessun errore è avvenuto ma è stato incontrato il record endfile
non potendo così completare l'operazione di ingresso per mancanza di dati.
Il valore effettivo di v dipende dal sistema, e può essere controllato dopo l'operazione di l/O per poter decidere le opportune azioni successive.
Esempio 18.3. Uso dello specificatore 10STAT. Si consideri il seguente segmentodi programma:
READ (1,50, IOSTAT = KS) A, B, CIF (KS.LT.O) THEN
C FINE DEL FILE
ELSEC CONTINUAZIONE DELLA NORMALE ELABORAZIONE
ENDIFSTOP
50 FORMAT (3 EI3.6)END
nelle quali si suppone l = l.
WRITE (UNII = 2, FMT = 60) A, B, CWRIIE (J, '(IX, 3E13.6)') A, B, CWRIIE (FMT = 60, UNII = l + I) A, B, CWRIIE (2, 60) A, B, CWRIIE (J, 60) A, B, CWRIIE (UNII = 2, FMT = '(IX, 3E13.6)') A, B, C
60 FORMAT (IX, 3E13.6)
nelle quali si suppone J = 2 e l = l.
CELSE IF (KS.GT. O) THENCONDIZIONE D'ERRORE DURANTE LA LETTURA
358 359
Esempio 18.4. Simulazione dell'esempio 18.3 tramite gli specificatori ERR eEND.
La lista di controllo presente nella READ specifica che la lettura avviene dal
file associato all'unità l secondo le modalità di conversione date nella frase
FORMAT di etichetta 50; lo stato al termine dell' operazione è codificato nella
variabile intera KS e l'esecuzione procede in base al valore di KS che viene controllato nella struttura IF successiva.
Negli specificatori di errore ERR = s e di fine file END = s, s è l'etichetta diuna frase eseguibile appartenente alla medesima unità di programma.
Il significato di tali specificatori è il seguente: il controllo viene trasferito
all'istruzione etichettata con s se durante l'operazione si sia verificata una condi
zione di errore per il primo o se, in lettura, sia stato incontrato il record endfile
su un file esterno o sia stato fatto un tentativo di leggere oltre la fine di un fileinterno per il secondo.
Si ricordi che, come già sopra accennato, una condizione di errore può essereprovocata da vari eventi fra i quali un disaccordo in tipo fra l'elemento della lista
di I/O ed il descrittore ripetibile associato nella specificazione di formato oppure un
errore di conversione dovuto alla presenza nel campo di ingresso di un carattere
non valido, oppure un disaccordo fra le caratteristiche assunte per il file associato
all'unità presente nella lista di controllo e quelle effettivamente dichiarate nellafrase OPEN per quell'unità.
0'! Inoltre, se durante un 'operazione di lettura si verifica una condizione di fine/I file o di errore, i valori degli elementi della lista di ingresso diventano indefiniti. A
Infine, se nella lista di controllo non è presente né lo specificatore 10STAT
né END né ERR e si verifica una condizione di errore o fine file, ciò provoca una
condizione d'errore per il programma la cui esecuzione, secondo il FORTRAN77, deve cessare.
L'ultimo specificatore, REC = n, dove n è un'espressione intera, riguarda le
operazioni di I/O su files ad accesso diretto che verranno illustrate nel § 18.6.
18.4. Connessione di un file esterno: frasi OPEN e CLOSE
Per poter fare riferimento in una frase di I/O ad un file esterno occorre che
questo sia «conosciuto dal programma», ossia connesso o associato ad una data
unità. I files relativi alle unità di I/O standard sono sempre connessi per tutti i
possibili programmi; essi si dicono pertanto files preconnessi e la dichiarazione
di connessione che vedremo è per essi implicitamente sempre assunta.
Alcuni sistemi prevedono anche la possibilità di preconnettere un file, ad esem
pio alla stampante o al lettore di schede etc., tramite opportuni comandi rivolti
allinker.
Frase OPEN
Con una dichiarazione di connessione rendiamo accessibile ad un programma
un file che già esiste su qualche supporto esterno, dichiarandone le caratteristiche
e potendo così leggerlo o modificarlo. Si pensi, ad esempio, ad un file esistente
relativo agli stipendi degli impiegati di una ditta. Esso sarà memorizzato su un
disco magnetico e conosciuto all'interno del sistema con un nome, poniamo
STIPENDI. Se vogliamo aggiornare tale file dobbiamo renderlo accessibile da par
te del programma di aggiornamento e ciò viene appunto fatto connettendo tale
file, identificato dal suo nome, ad una certa unità di I/O rappresentata dall'oppor
tuno valore intero.
Se, d'altra parte, il file non esiste esso può venire creato dandogli un nome e de
finendolo con opportune operazioni di scrittura; questo file potrà poi essere me
morizzato permanentemente, su qualche supporto esterno a seconda delle speci
fiche date al riguardo.
In ogni caso. per tutti i files che non siano preconnessi occorre che essi sianoesplicitamente connessi tramite l'uso della frase OPEN che ha la seguente forma:
READ (1,50, ERR = 100, END = 200) A, B, CCONTINUAZIONE DELLA NORMALE ELABORAZIONEc
i
'II
i I
IlIi
~ II
r
GOT060C CONDIZIONE D'ERRORE
100
GO TO 60C FINE DEL FILE
200
60 STOP50 FORMAT (3E13.6)
END
OPEN (olista)
dove:
• OPEN è la parola chiave che identifica la frase;
• olista è una lista composta da tutti o parte dei seguenti specificatori separati
da virgole:
I 1l'·t
I
STATUS = st
Con lo specificatore di stato
STAMPA SUL MEZZO PRN.
WRlTE (2, 'C'v STAMPAvSULvMEZZOvPRN")'}
associa il file (stampante) PRN all'unità 2, così la successiva istruzione
OPEN (UNlT = 2, FILE = 'PRN')
file identificato, può essere diverso per ogni esecuzione del programma in cui leistruzioni sopra riportate compaiono: le istruzioni di I/O che nel corso di quel
programma si riferiscono all'unità 6 comportano così operazioni di I/O sul file
individuato dal valore attuale di NOMEFI.
361
produce sulla stampante, la linea
dove:• st è una espressione di tipo carattere che deve valere una delle seguenti stringhe: 'OLD', 'NEW', 'SCRATCH' o 'UNKNOWN', stabiliamo certe caratteristiche
sulla vita del file il cui nome è presente nella stessa frase OPEN.Se st vale 'OLD' allora il file deve già esistere, mentre se vale 'NEW' esso non
deve preesistere. Se un file con specifica 'NEW' viene connesso, allora il suo stato
viene mutato in 'OLD' così che ogni successivo tentativo di riconnettere quel
file con STATUS uguale a 'NEW' fallisce, ciò per evitare eventuali modifiche ac
cidentali di un file già esistente. Se st vale 'SCRATCH' si ha la creazione di un
file speciale di esclusivo uso da parte del programma, la sua durata è quella del
l'esecuzione del programma: quando l'esecuzione del programma termina anche
il file cessa di esistere. Evidentemente, se la dichiarazione del file prevede lo specificatore FILE, il file non può essere di tipo SCRATCH. Se st vale 'UNKNOWN'o se lo specificatore di stato è omesso, lo stato del file dipende dal sistema: generalmente, se il file già esiste, lo stato assunto è 'OLD', altrimenti è 'NEW'.
Esempio 18.6. Scrittura sulla stampante. Supponiamo che nel sistema di calcolo
in uso la stampante sia identificata dal nome PRN. La seguente istruzione
CHARACTER • 8 NOMEFIREAD '(A)', NOMEFIOPEN (UNIT =6, FILE = NOMEFI)
FILE = 'PRN', FILE = 'CON', FILE = 'STIPENDI'
FILE = 'A:VAL.DAT'
dove n è un'espressione di tipo carattere, ad esempio possiamo avere:
FILE = n
UNIT = u
FILE = nSTATUS = stACCESS = ace
FORM = formRECL = 2BLANK = bi
ERR = s10STAT = v
Esempio 18.5. Uso di un nome variabile di file
Il primo specificatore, UNIT = u o semplicemente u, deve essere sempre
presente, mentre gli altri sono facoltativi. In questo specificatore, u ha la forma
già illustrata nel § 18.3.
Il file che deve essere associato all'unità u deve avere, se già esiste, un nome che
sia conosciuto dal sistema, ad esempio il nome che tale file ha se memorizzato
su nastro o disco, oppure il nome che il sistema dà ai files che rappresentano i
comuni mezzi di I/O, quali la stampante o la telescrivente, come PRN, LPT o
CON e simili. Tale nome è quello che deve comparire nello specificatore
360
Le espressioni, in questo caso costanti, 'PRN', 'CON', 'STIPENDI' e
,A : VAL.DAT' sono possibili nomi di files riconoscibili dall'attuale sistema di
'Icalcolo. Per quanto riguarda i nomi dati dal sistema ai comuni mezzi di I/O e
l/I 1, la forma corretta per i nomi di files sui vari supporti magnetici occorrerà il~''l' consultare il relativo manuale del sistema. Oltre a nomi costanti di files si possono' I
usare anche nomi variabili, come mostra il seguente esempio.
Con queste istruzioni viene letta, dal mezzo standard di ingresso, una stringa
di caratteri e assegnata alla variabile carattere NOMEFl che, nella successiva frase
OPEN, costituisce il nome del file associato all'unità 6. Tale nome, e quindi il
Esempio 18.7. Connessione del file esistente, 'A: VAL.DAT', all'unità 6, con
una delle successive istruzioni OPEN equivalenti:
OPEN (6, FILE = 'A:VAL.DAT', STATUS = 'OLD')OPEN (6, FILE = 'A:VAL.DAT', STATUS = 'UNKNOWN')OPEN (6, FILE = 'A:VAL.DAT').
d
II
~!
I
I
362
Lo specificatore
ACCESS = ace
dove:
• ace è un'espressione carattere che deve valere 'SEQUENTIAL' o 'DIRECT'
dichiara il modo di accesso al file. Con 'SEQUENTIAL' il modo di accesso è se
quenziale, con 'maser è invece diretto; nel § 18.6 verranno illustrate le caratteristiche e l'uso dei files ad accesso diretto. Se lo specificatore ACCESS è omesso
_vie~ne assunto il modo sequenziale: i files -connessi con le istruzioni OPEN dagliesempi precedenti sono allora tutti ad accesso sequenziale.
Già abbiamo illustrato la possibilità di usare records con e senza formato.
Un file può essere costituito da records tutti con formato o tutti senza formatoin accordo con lo specificatore
FORM = form
dove:
• form è un'espressione carattere che deve valere 'FORMATTED' o'UNFORMATTED', rispettivamente per files con e senza formato.
~I
~_t~edficatore è omesso iLfìle è considerato dal sistema con formato '(ryr; I se l'accesso è .sequeneiale, ma senza formato se l'accesso è diretto. Alloratlì"ill li: ,iV
!i files degli esempi precedenti sono costituiti da~eooids~conToimato e ad ac;ces~-L1JI·1 so sequenziale. p
- ---Ili
Esempio 18-8- Connessione di un file sequenziale con formato di tipo SCRATCHall'unità I:
OPEN (I, STATUS = 'SCRATCH', ACCESS = 'SEQUENTIAL',• FORM = 'FORMATTED').
Quando un file sia stato dichiarato ad accesso diretto è necessario stabilire apriori la lunghezza, costante, dei suoi records, misurata in caratteri per i records
con formato o in base all'unità di misura adottata dal sistema per quelli senza formato. Tale dichiarazione viene fatta tramite lospecificatore
RECL = ~
dove:
• ~ è un'espressione intera il cui valore dà l'opportuna informazione sulla lunghezza.
f\I\J Si noti che tale specificatore non deve essere presente se il file è stato dichiarato" r~ ad accesso sequenziale. [,J \
1363
Esempio 18.9. Si considerino le seguenti frasi:
OPEN (6, FILE = 'A:DIR.DAT', ACCESS = 'DIRECT', STATUS = 'OLD',*RECL = 8)
OPEN (7, FILE = 'C:VAL.FM', ACCESS = 'DIRECT', STATUS = 'NEW',*FORM = 'FORMATTED', RECL = 8) -
La prima associa all'unità 6 il file identificato dal nome A :DIR.DAT, già esi
stente e memorizzato su un supporto magnetico. Le sue caratteristiche sono di
essere: ad accesso diretto con records senza formato (il dichiaratore FORM è
infatti assente e l'accesso è diretto); la lunghezza di ciascun record è 8 unità.
La seconda frase OPEN associa all'unità 7 il file che verrà creato con il nomeC:VAL.FM. Le sue caratteristiche sono di essere: ad accesso diretto con records
con formato di lunghezza 8 caratteri ciascuno.
Nella definizione delle caratteristiche di un file costituito da records con for
mato, possiamo stabilire il modo di interpretare i caratteri blank all'interno di
campi numerici: ignorarli o considerarli come cifre zero. A questo scopo esistelo specificatore
BLANK = bI
dove:
• bI è un'espressione carattere che deve valere 'NULL' o 'ZERO' a seconda se
vogliamo ignorare o considerare come zero i caratteri blanks nei campi numerici,
tenendo conta.checomunque un campo composto da tutti blanks è considerato
contenere il valore zero.
Se tale specificatore è omesso, viene assunta l'opzione 'NULL'. Ricordiamo
inoltre che tale scelta può essere ulteriormente, di volta in volta, cambiata con
l'uso dell'apposito descrittore non ripetibile BN o BZ all'interno di una specifi
cazione di formato (cfr. cap. 13LL~~ec_i!icatore BLANK infine, non deve essere
presente se il file è costituito da records senza formato.- ---"- - -- ._- ----
Il trattamento delle condizioni di errore che si possono verificare durante la
connessione di un file è stabilito con gli ultimi due specificatori ERR e IOST AT.
Una condizione d'errore si potrebbe presentare nel caso in cui un file dichiarato
come 'OLD' non esista o se il tipo del file esistente non si accorda con quello stabilito da certi specificatori.
Ricordiamo che in queste circostanze. se nessuno dei due specificatori ERR oIOST AT è presente si ha un arresto dell'esecuzione del programma.
Con lo specificatore
ERR =s
/ ,
364
dove:
• s è l'etichetta di una frase appartenente alla medesima unità di programmasi stabilisce che in caso di errore l'esecuzione riprenda a partire dalla frase di eti
chetta s.
Se è presente lo specificatore:
IOSTAT = v
dove:
• v è un nome di variabile o elemento di variabile dimensionata di tipo intero,
allora in relazione al verificarsi o meno di errori v assume i seguenti valori:
• zero se nessun errore è avvenuto;• un valore positivo dipendente dal sistema in caso contrario.
La variabile v può essere controllata per avere informazioni sull'esito dell'o
perazione di connessione.
(vJ Tenendo presente la re~.ola generale. che una unità non Pliò ~sse~e _co~~:~so:,'contemporaneamente a ptu files, possiamo avere una corretta connessione neil{
casi seguenti:
a) se il file nella OPEN è diverso da quello già connesso, allora il file preceden
te viene sconnesso (vedi frase CLOSE più avanti) ed il nuovo file viene connesso'b) se il file nella OPEN è il medesimo, ossia già connesso, oppure se l'unità
indicata è una di quelle preconnesse, allora l'unico specificatore consentito è il
BLANK per stabilire esplicitamente l'interpretazione dei blanks.
I, Il In ogni caso è P!~ibito tentare d~ _~~n.!!~!.ereu~y-nit4a~ un file che sia già /',' \,, \ \ associato ad un 'altra unità. -- - I
Frase CLOSE
Al termine dell'esecuzione di un programma ogni file che sia stato connesso
viene automaticamente sconnesso o chiuso.Se vogliamo operare tale sconnessione prima della fine del programma perché
desideriamo ad esempio riconnettere quel file ad altra unità, possiamo usare la
frase
CWSE (cllista)
dove:• cllista è una lista composta da uno o più dei seguenti specificatori separatida virgole:
365
u
UNIT = u
STATUS = st
ERR = sIOSTAT = v
Lo specificatore u oppure UNIT = u deve essere sempre presente. Gli speci
fica tori u, UNIT, ERR e IOSTAT hanno il medesimo significato visto nella frase
OPEN.Con lo specificatore
STATUS = st
dove:• st è un'espressione carattere che deve valere 'KEEP' o 'DELETE', si danno
indicazioni sulla possibilità o meno di riconnettere il file durante l'esecuzione
del programma. Se st vale 'KEEP' il file che era connesso all'unità u può essere
successivamente connesso alla medesima o altra unità; se invece st vale 'DELETE',
il file connesso all'unità u cessa di esistere: ciò significa che il file non può essere
ulteriormente connesso durante l'esecuzione del programma e non vuoI dire che
il file deve essere cancellato dalla memoria ausiliaria sulla quale è memorizzato.
Se lo specificatore STATUS è omesso, viene automaticamente assunta la di
chiarazione KEEP a meno che il file in questione non sia stato connesso con la
specifica STATUS = 'SCRATCH', nel qual caso viene assunta la dichiarazione
DELETE.Ricordiamo infine che le frasi OPEN e CLOSE non esistevano in F66.
Esempio 18.10. Le seguenti frasi
OPEN (6, FILE = 'C:VAL.DAT', STATUS = 'OLD')
CLOSE (6, STATUS ='KEEP')
OPEN (7, FILE ='C:VAL.DAT')
implicano la connessione del file CVAL.DAT all'unità 6, quindi la sconnessione
da quella unità e la successiva riconnessione di quel file all'unità 7.
18.5. Frasi di posizionamento: BACKSPACE e REWIND
Può essere utile poter esplicitamente posizionare la testina di lettura/scrittura
di un mezzo magnetico su di un record voluto di un file sequenziale.
I
Ii i
t
IIl
I,,
1-1 I
n\,
I
366 367
A tale scopo esistono le frasi
BACKSPACE u oppure BACKSPACE (auxlista)
e
REWIND u oppure REWIND (auxlista)
tutti i records successivi.Le istruzioni BACKSPACE e REWIND vengono usate di solito solo per leggere
i records di un file. Vedremo comunque che i files ad accesso diretto consentonoun aggiornamento dei loro records nel senso che è possibile modificare un certo
record lasciando inalterati tutti i precedenti ed i successivi.
Si osservino le tre frasi
esse realizzano in modo assai semplice il posizionamento sul record endfile del fileESPER.DAT. La frase READ non contiene alcuna lista, ma la sua esecuzione,
5 READ (8, END = lO)GOTOS
lO BACKSPACE 8
PROGRAM AGGESPDICHIARAZIONIREAL TEMPINTEGER DATA (3), ORA (3)LETTURA DATI DAL MEZZO STANDARD D'INGRESSO
READ., TEMP, DATA, ORAIL FILE ESPER. DAT E' ASSOCIATO ALL'UNIT A' 8OPEN (8, FILE = 'ESPER.DAT', STATUS = 'O~D', FORM =
.'UNFORMATTED', ACCESS = 'SEQUENTIAL )POSIZIONAMENTO SUL RECORD ENDFILE
5 READ (8, END = lO)GOTOS
lO BACKSPACE 8I DATI LETTI VENGONO SCRITTI COME ULTIMO RECORDDEL FILE AL POSTO DI ENDFILE, CHE VIENE ULTERIORMENTE
AGGIUNTO AL FILEWRITE (8), TEMP, DATA, ORAENDFILE 8STOPEND
CCC
C
C
C
c
Esempio J8. J2. Si vuole aggiornare un file di nome ESPER.DAT, i cui .recordscontengono i valori: temperatura, data ed ora relativi ad un certo espenmento.Tali records sono senza formato ed il file è ad accesso sequenziale, vogliamo infatti solo aggiungere alla fine del file il record relativo all'ultima rilevazione fatta,
l'ultimo record del file è il record end file.Un semplice programma per realizzare quanto sopra detto, dovrà contenere le
specifiche del file in una opportuna frase OPEN, dovrà prevedere la lettura dei
dati che devono essere aggiunti al file. Siano questi TEMP per temperatura,
DATA (3) il vettore di 3 componenti per giorno mese ed anno ed il vettore
ORA (3) di 3 componenti per ora, minuti e secondi.
WRITE (2, '(lOE13.6)') VBACKSPACE 2
Esempio J8. JJ. Le seguenti frasi
fanno si che venga scritto sul file SEQ un record e successivamente provocano il
posizionamento della testina all'inizio del record appena scritto.
REAL V(lO)OPEN (UNIT = 2, FILE = 'SEQ', ACCESS = 'SEQUENTIAL')
dove:
• u è l'identificatore di unità come già precedentemente illustrato;
• auxlista è la lista di specificatori UNIT, ERR e 10STAT già illustrati nel
§ 18.2, in cui lo specificatore UNIT deve necessariamente essere presente.
L'esecuzione di BACKSPACE fa si che la testina si posizioni all'inizio delrecord appena trasmesso; ciò consente, ad esempio, di rileggere un record appena
letto.
Si noti che all'inizio dell'esecuzione di un programma, per ogni file connesso,
il record che sta per essere letto è il primo. Ovviamente, eseguendo più volte una
BACKSPACE è possibile il posizionamento su un record precedente.Se, d'altra parte, desideriamo ritornare all'inizio del file è conveniente l'uso
della REWIND, che causa appunto il posizionamento sul primo record del fileassociato ad u nella REWIND stessa.
f r L'uso di tali frasi è particolarmente utile in connessione con l'uso del record
\ l' !endfile. Quando un tale record sia stato letto o scritto, nessuna ulteriore opera\ zione di I/O può essere effettuata sul file in questione senza prima aver eseguito
una frase BACKSPACE o REWIND.
IOccorre mettere in evidenza una importante caratteristica dei files ad accesso
r sequenziale. Quando un record viene scritto su di un file sequenziale, esso è l'ul\ I, timo record del file, COSI' ogni eventuale altro record su~~essivo presente sul file, vtene distrutto. Non possiamo allora usare le frasi BACKSPACE e REWIND per
\ \ I posizionarsi su un certo record, riscriverci sopra una nuova versione lasciando irecord successivi inalterati: lascrittura del nuovo record è possibile solo perdendo'
368
18.6. Files ad accesso diretto
Abbiamo già messo in luce il fatto che usando come memoria ausiliaria il disco
magnetico, che può essere disco rigido o fisso o dischetto (floppy disk), riusciamo
ad ottenere da una parte prestazioni, riguardo ai tempi d'accesso, molto miglion
rispetto ai nastri e dall'altra la possibilità di accedere ai records di un file, se ilmodo d'accesso è DIRECT, in modo non sequenziale ma stabilito in base al nu
mero d'ordine del record voluto. Tale possibilità di accesso diretto, detto anchecasuale, è data dalla struttura fisica del mezzo che riportiamo in fig. 18.1.
j.
\
~:
Ii
369
RECL =2
come già illustrato nel § 18.4.
dove n è un'espressione intera.
Ricordiamo che per dichiarare un file ad accesso diretto, dobbiamo includere
nella frase OPEN lo specificatore
ACCESS = 'DIRECT'
e dobbiamo altresì dichiarare la lunghezza di ciascun record del file con lo spe
cificatore
binazione del movimento orizzontale «avanti-indietro» della testina e di quello
di rotazione del disco, consente il posizionamento della testina in qualsiasi punto
di qualsiasi traccia. Ovviamente il tempo massimo richiesto per accedere ad unrecord è quello necessario per lo spostamento della testina dalla traccia più in
terna a quella più esterna, o viceversa, più quello per un giro completo del disco.
Le caratteristiche di velocità d'accesso del disco lo hanno fatto di gran lunga
preferire al nastro per quasi tutte le applicazioni, tanto che oggi il sistema operativo di un elaboratore è basato proprio sul disco, si pensi ad esempio alla categoria
dei sistemi DOS (Disk Operating System).Il fatto che il disco consenta l'accesso diretto ai records di un file non implica
che necessariamente tutti i files su di esso memorizzati siano ad accesso diretto;come è già stato osservato, possono essere definiti sul disco anche files ad acces
so sequenziale.I files ad accesso diretto risultano particolarmente utili in determinate circo
stanze: quando si voglia leggere un record senza dover necessariamente scorrere
tutti i precedenti o quando si voglia riscrivere su di un record una nuova versione
senza perdere i records successivi.Per accedere ad un record su di un file ad accesso diretto, occorre conoscere
il numero d'ordine, in quanto tutti i records di un file sono ordinati. Il numero
d'ordine del record interessato all'operazione di I/O deve essere specificato nella
lista di controllo della frase di I/O mediante lo specificatore
REC=n
Testina dilettura/scritturaTraccia
provocando comunque la lettura di un record, i cui valori non sono assegnati ad
alcuna variabile, genera uno «scorrimento» del file che viene ripetuto per effettodella frase GOTO 5 finché non viene letto il record endfile. A questo punto lo
specificatore END = lO provoca il salto alla frase lO BACKSPACE 8 la qualeposiziona la testina sul record appena letto ovvero sul record endfile. La succes
siva frase WRITE provoca la sostituzione del record endfile con quello senza for
mato, costituito dai sette valori di TEMP, DATA e ORA. La successiva frase
ENDFlLE 8 scrive il nuovo record endfile. La fine dell'esecuzione del programma
comporta quindi l'automatica sconnessione del file come se fosse eseguita una
frase CLOSE (8).
Figura 18.1. Struttura dell'unità disco magnetico.
L'unità disco magnetico è infatti costituita da un disco, le cui facce sono ri
coperte da materiale magnetico, che ruota intorno ad un asse verticale; sul disco
si muove orizzontalmente una testina di lettura/scrittura.L'informazione è memorizzata su tracce concentriche, di modo che la com-
Esempio 18.13. Si considerino le seguenti frasi:
OPEN (7. FILE = 'ACCDIR', ACCESS = 'DI RECT' ,*FORM = 'UNFORMATTED', RECL = 12)
WRITE (7, REC = 2) X, Y, Z
READ (7, REC = 2) A, B, C
370
La prima frase dichiara le seguenti caratteristiche del file di nome'ACCDIR'associato all'unità 7: esso è ad accesso diretto e i suoi records senza formato sonolunghi 12 unità.
La seconda scrive come secondo record del file 'ACCDIR' un record (di lunghezza 12) composto dai 3 valori di X, Y e Z rispettivamente. La terza causa
la lettura del 20 record del file 'ACCDIR' e definisce le variabili A, B, C con i valori, senza alcuna conversione, di X, Y, e Z precedentemente scritti.
Esempio 18.14. II seguente programma:
PROGRAM MEDVALREAL MEDIADIMENSION A(20), MEDIA (50)
C CONNESSIONE DEL FILE 'VALORI' ALL'UNITA' 2
OPEN (UNIT = 2, FILE = 'VALORI', ACCESS = 'DIRECT', RECL = 80,*STATUS = 'OLD')
C LETTURA DEI VALORI DI M E N, CON M MINORE O UGUALE A 20C E N MINORE O UGUALE A 50 (NUMERO TOTALE DEI RECORDSC PRESENTI NEL FILE 'VALORI')
READ *,M,N
C DEFINIZIONE DEL VETTORE A E DEL VETTORE MEDIA,C TRAMITE LA LETTURA DI UN RECORD PER VOLTA DAL FILE
DOSI=I,NREAD (2, REC = I) (A(J), J = 1, M)MEDIA (I) = O.D04K=I,MMEDIA (I) = MEDIA (I) + A(K)
4 CONTINUEMEDIA (I) = MEDIA (I)/MCONTINUE
C STAMPA SULLA STAMPANTE 'PRN' DEL VETTORE MEDIA,C IL FILE 'PRN' VIENE ASSOCIATO ALL'UNITA' 3
OPEN (3, FILE = 'PRN')WRITE (3, 6) MEDIASTOP
6 FORMAT (IOX, 'VETTORE MEDIA RICAVATO DAL FILE VALORI'/*5 (2X, EI3.6))
END
definisce le prime N componenti del vettore MEDIA. Ciascuna componente è la
media degli M valori letti da ciascuno dei primi N records del file 'VALORI'
associato all'unità 2. Questo file è ad accesso diretto ed è costituito da records
senza formato di lunghezza 80 (= 20 x 4 unità). Esso deve essere stato precedentemente definito in modo tale da contenere in ciascuno dei primi N records al
meno M valori. II vettore MEDIA calcolato viene stampato sul file stampante'PRN' di tipo sequenziale costituito da records con formato, associato all'unità3.
371
Abbiamo già notato che la lunghezza dei records, in un file ad accesso diretto,
deve essere sempre la medesima, quella definita nello specificatore RECL.
D'altra parte in F77 è possibile scrivere un record senza formato di lunghezza
inferiore a quella stabilita; in questo caso la parte mancante viene riempita con
valori indefiniti. Ciò è possibile anche con records con formato di un file ad
accesso diretto: in questo caso il record eventualmente più corto viene allungato
con dei caratteri blanks per raggiungere la lunghezza stabilita.
Esiste poi un altro tipo di automatismo nelle operazioni di 110 ad accesso di
retto con formato: se la specificazione di formato e la lista di 110 sono tali datrasmettere più di un record, allora ogni record trasmesso viene numerato aggiungendo una unità al numero d'ordine del record precedente. Così le frasi
OPEN (3, FILE = 'DIRFORM', ACCESS = 'DIRECT',*FORM = 'FORMATTED', RECL = 100)
WRITE (3, 30, REC = l) (A(I), I = 1,20)30 FORMAT (lO GIO.2)
provocano la scrittura, sul file 'DIRFORM', di due records ciascuno costituito
da lOdati rappresentati in accordo al descrittore G l0.2; il primo record ha nu
mero d'ordine 1 ed il secondo ha numero d'ordine 2. Si noti, infine, che se il file
'DIRFORM' contenesse già il primo ed il secondo record, questi verrebbero sosti
tuiti da quelli appena scritti.
18.7. Indagine sulle unità di 110e sui files: frase INQUIRE
Può essere utile avere la possibilità di sapere le caratteristiche di files esterni
conosciuti dal sistema eia unità usate in un programma. Ciò può essere ottenutoeseguendo la frase INQUIRE che definisce il valore di variabili el» elementi divariabile dimensionata, in modo tale da sapere se un tile è costituito da records con
formato, se è ad accesso diretto o sequenziale e così via.La frase in questione è la seguente
INQUIRE (i1ista)
dove
• INQUIRE è la parola chiave che identifica la frase;
• ilista è una lista di specificatori, separati da virgole, scelti fra i seguenti:
u
UNIT = u
FILE = nl
ACCESS = ace
FORM = fm
372373
(( f~
'SEQUENTIAL' o 'DIRECf' se il file è connesso per un accesso sequenziale odiretto, ma resterà indefinita se non c'è alcuna connessione. Analogamente, fmassume il valore 'FORMATIED' o 'UNFORMATTED' a seconda del tipo di connessione, ma resta indefinita se non c'è connessione. Ancora, ~ assume come valorela lunghezza dei records del file se questo è connesso con un accesso diretto, altrimenti resta indefinita; bi assume il valore 'ZERO' o 'NULL' a seconda dei casi,ma resta indefinita se non c'è connessione o se il file è costituito da records senzaformato.
RECL = ~
BLANK = biSEQUENTIAL = seqDIRECf = dirFORMATTED = fmtUNFORMATTED = unfEXIST = ~l
OPENED = ~2
NAMED = ~3
NUMBER=numNAME = n2NEXTREC = nrERR =sIOSTAT = v
Viceversa, gli specifica tori
SEQUENTIAL = seq, DIRECf = dir,UNFORMATTED = unf
FORMATTED = fmt,
. Negli specificatori indicati tutti gli elementi alla destra del segno di uguaglianza devono essere nomi di variabile o nomi di elementi di variabile dimensionataad eccezione di u e di nl che possono anche essere un'espressione intera e un'espressione carattere rispettivamente. In particolare, ace, fm, bi, seq, dir, fmt,unf e n2 sono di tipo carattere; ~ l, ~2 e ~3 sono di tipo logico; ~, num, nr e v sonodi tipo intero e s è un'etichetta di una frase eseguibile appartenente alla medesima unità di programma.
Con questa frase possiamo conoscere le caratteristiche di un file attraverso ilsuo nome anche se non è connesso ad alcuna unità, oppure quelle di un file connesso ad una data unità.
1Nel primo caso nella ilista deve essere presente lo specificatore FILE ed as-j
"li sente quello UNIT, nel secondo deve essere presente lo specificatore UNIT e non \'1}quello FILE.
La presenza degli altri specificatori è facoltativa; in generale, l'effetto dell'esecuzione di una frase INQUIRE è quello di assegnare dei valori alle entità variabilinegli specificatori. In alcuni casi, però, tale assegnazione può non avvenire e lacorrispondente entità resta indefinita.
Per molti versi gli specificatori della INQUIRE sono simili a quelli della OPEN,però con un effetto diverso.
Così gli specifica tori l(
ACCESS = ace, FORM = fm, RECL =~, BLANK = bi
fanno sì che ace, fm, ~ e bi diventino o meno definite: ace assumerà il valore
'. . consentono di conoscere le corrispondenti caratteristiche di un file anche se'\' questo non è connesso. 11 '
In ogni caso seq, dir, fmt e unf vengono definite con i valori 'VES' 'NO' o'UNKNOWN'. '
Così seq assume il valore 'VES' se il file consente l'accesso sequenziale, 'NO' senon lo consente e 'UNKNOWN' se da parte del sistema non è possibile determinare questa caratteristica. Per gli altri tre specificatori e relativi elementi dir, fmte unf valgono le stesse considerazioni fatte per lo specificatore SEQUENTIAL.
Con l'uso degli specifica tori
EXIST =~l, OPENED =~2, NAMED =B
~l, ~2, ~3 assumono un valore logico, .TRUE. o .FALSE.. a seconda del verificarsi o meno della corrispondente condizione. Con EXIST viene effettuato ilcontrollo se il file specificato o l'unità specificata esiste. Con OPENED, ~2 risultavera se il file specificato è connesso a qualche unità, o se l'unità specificata è connessa a qualche file, falsa altrimenti. Con lo specificatore NAMED, ~3 assume il
valore vero se il file connesso ha un nome, falso altrimenti.
Gli specificatori
NUMBER = num, NAME = n2
definiscono num e n2 rispettivamente con il numero dell'unità attualmente con-
~.
\l
i
. ~ .rs1tm--------- .....
374
nessa al file specificato e con il nome del file attualmente connesso all'unità spe
cificata. Se non c'è alcuna unità connessa al file num resta indefinita; altrettanto
n2 resta indefinita se il file connesso all'unità non ha un nome.
Riguardo ancora allo specificatore NAME c'è da notare che se esso appare inuna frase INQUIRE in cui figura lo specificatore FILE, il valore assunto da
n2 può non essere uguale a quello riportato nello specificatore FILE; ad esem
pio il valore di n2 può contenere anche una sigla di identificazione relativa all'u
tente. Se poi nessun file è connesso all'unità specificata n2 rimane indefinita.
375
Esempio 18.15. Si considerino le seguenti frasi
LOGICAL LOG
INQUIRE (FILE = 'V A.L.DAT', OPENED = LOG, NUMBER = NUM)
IF (LOG) THENC IL FILE VAL.DAT E' GIA' CONNESSO ALL'UNITA' NUM
WRITE (NUM) A, B, C
ElSEIL FILE VAL.DAT NON E' CONNESSO AD ALCUNA UNITA',ESSO VIENE ALLORA ASSOCIATO ALL'UNITA' 3
OPEN (3, FILE = 'VAL.DAT') r t r ( (C /1 l Cfltlr 1( e
Lo specificatore
NEXTREC = or
causa la definizione di or con il valore m + l dove m è il numero d'ordine dell'ul
timo record trasmesso da o verso il file se questo è ad accesso diretto; se nessun
record è stato trasmesso allora nr assume il valore 1. Se invece il file non è ad
accesso diretto o se è avvenuto un errore durante la trasmissione tale da rendere
indefinita la posizione richiesta, or resta indefinita.
CC
WRITE (3) A, B, C
ENDIF
:::, ( y , \ l" \4 ~ ( (I ( A I C (, 1(1 f C
Lo specificatore
IOSTAT = v
definisce v con il valore zero se non esiste alcuna condizione d'errore relativa al
file o all'unità specificata nella INQUIRE, oppure con un numero positivo, dipen
dente dal sistema, se, al contrario, esiste una condizione d'errore.
Lo specificatore
ERR=s
ha il medesimo significato illustrato nel § 18.4.
Una variabile o elemento di variabile dimensionata che figura in uno degli spe
cificatori della frase INQUIRE non può essere presente in nessun altro specifica
tore della medesima frase INQUIRE; tale divieto si estende anche a tutte le entità
che in qualche modo sono associate, ad esempio tramite la frase EQUIVALENCE,
a quella variabile o elemento di variabile dimensionata.
Notiamo infine che la frase INQUIRE non esiste in F66.
Con la frase INQUIRE siamo in grado di sapere se il file VAL.DAT è connesso
o meno e in caso affermativo a quale unità. Se il file è già connesso LOG assume
il valore vero e NUM il valore intero che identifica l'unità a cui il file è connesso.
Con la struttura IF successiva, in base al valore assunto da LOG si possono com
piere operazioni di 110 sull'unità NUM se LOG è vera oppure in caso contrario il
file VAL.DAT viene connesso all'unità 3 tramite la quale si compiono ancora
operazioni di 110 sul file.
18.8. Files interni
Un file interno può essere considerato come una zona di memoria di transito,
utile per dei trasferimenti, con eventuali conversioni, di dati da una parte all'altra
della memoria entrambe interne.Un file interno è una delle seguenti entità di tipo carattere: una variabile, un
elemento di variabile dimensionata, una sottostringa o una variabile dimensionata.
Se un tale file è una variabile o elemento di variabile dimensionata o una sotto
stringa allora è costituito da un solo record, mentre se è una variabile dimensio
nata esso è costituito da tanti records Quanti sono gli elementi della variabile.Qualunque operazione di I/O su di un file interno inizia sempre dal primo record
del file.II riferimento al file avviene direttamente nella frase di 110usando il suo nome
come identificatore della unità di I/O. Tali operazioni devono essere di tipo
376
sequenziaie sotto il controllo esplicito di formato.Una entità usata come file interno può essere definita oltre che con una
operazione di scrittura, anche, ad esempio, tramite una operazione di lettura da
un'altra unità, o con operazioni di assegnazione di tipo carattere.Se durante un'operazione di scnttura su di un file interno viene prodotto un
record di lunghezza inferiore a quella specificata per il file il record prodotto vieneallungato con l'aggiunta alla sua destra di caratteri blank.
Tale tipo di file non esisteva in F66, nè quindi le corrispondenti operazioni
di I/O.
Esempio 18.16. Un file di nome ACCDIR ad accesso diretto contiene 25 records
con formato. Ciascun record è costituito da 4 campi contenenti dei numeri scritti
secondo il descrittore EI5.7, seguiti da un ultimo campo costituito da un valorelogico rappresentato secondo il descrittore LI. In totale quindi la lunghezza,in caratteri, di ciascun record è 61.
Siano N, O:s;;; N:S;;; 25, i records contenenti il valore vero nell'ultimo campo. Vogliamo definire le prime N righe di una matrice reale, RMAT, in modo tale che esse siano nell'ordine i 4 valori reali dei records che contengono nell'ultimo campo
il valore vero.
Possiamo far uso della variabile carattere TRANS di lunghezza 60 come file
interno in cui leggere i records di ACCDIR ed usarla poi come unità di ingresso
per definire, se è il caso, la riga opportuna di RMAT. Il seguente programma rea
lizza quanto sopra richiesto.
PROGRAM FIUNTLOGICAL L61CHARACTER * 60 TRANSREAL RMAT (25, 4)
C IL FILE 'ACCDlR' E' ASSOCIATO ALL'UNITA' 3C LE CARATTERISTICHE DI QUESTO FILE SONO DATE NELLA OPEN
OPEN (UNIT = 3, FILE = 'ACCDIR', FORM = 'FORMATTED', RECL =*61, ACCESS = 'DIRECT',STATUS = 'OLD')
IR = lDO 20 I = 1,25READ (2, 3, REC = I) TRANS, L61IF (L6l) THENREAD (TRANS, FMT = 4) (RMAT (IR, J), J = 1,4)IR = IR + lENDIF
20 CONTINUEIF (IR.EQ.l) THEN
PRINT *, 'NESSUN RECORD DI ACCDlR CONTIENE IL',*'vALORE VERO, RMAT NON Eli STATA DEFINITA'
zd
377
ELSEPRINT *, 'SONO STATE DEFINITE LE PRIME', IR - l,
*'RIGHE DI RMAT, NEL MODO SEGUENTE:'WRITE (*, 5) «RMAT (I, J), J = 1,4), I = l, IR - l)
END IFSTOP
3 FORMAT (A60, Ll)4 FORMAT (4E15.7)5 FORMAT (4 (IX, EI5.7»
END
Esempio 18.17. Vogliamo scrivere, usando un file interno, le opportune frasi
di l/O che permettano di arrotondare il valore di ciascuna componente Vi' l :s;;; i :s;;;100, di un vettore reale v precedentemente definito, a due cifre decimali, sup
ponendo che - 1000 :s;;; v; :s;;; 10000 per ogni i.
CHARACTER * 8 ARROT2 (IOO)DIMENSION VET (100)
c USO DEL VETTORE ARROTI COME FILE INTERNO, SULC QUALE VENGONO SCRITTI GLI ELEMENTI DI VETC CIASCUNO SECONDO IL DESCRITTORE F8.2
WRITE (ARROTI, '(F8.2)') VETC I VALORI ARROTONDA TI GIA' SCRITTI IN ARROT2C VENGONO RILETTI IN VET
READ (ARROn, '(F8.2)') VETC USO DI VET
Il file interno ARROT2 (100) viene definito, scrivendoci i valori di VET
tramite F8.2 che opera il voluto arrotondamento. Tali valori arrotondati vengono
poi riletti dal file ARROT2 per ridefinire VET. In entrambe le operazioni di
scrittura e lettura vengono scritti e letti esattamente 100 records sul e dal file
ARROT2.
Esercizi.
18.1 Scrivere le opportune frasi OPEN e WRITE per stampare dei dati su un file
chiamato LPT di tipo sequenziale costituito da records con formato.
18.2 Scrivere le frasi OPEN e REA D per definire la matrice A di lO righe e IOcolonne, leggendo i valori dei suoi elementi da un file di nome FIL.DATcomposto di records senza formato, di lunghezza 80 bytes (un valore è
rappresentato da 4 bytes), ad accesso diretto.
II!
f~j
l'Ii
378
18.3 Come l'esercizio 2, supponendo però il file ad accesso sequenziale.
18.4 Scrivere le frasi OPEN e READ per leggere i valori degli elementi di un
vettore VET di lunghezza 100 da un file chiamato PERIF, ad accesso di
retto con records con formato di lunghezza 20 caratteri. Ciascun recordcontiene 4 campi scritti secondo il descrittore FS.I. Il numero dei records
di PERIF può essere inferiore a 100, comunque l'ultimo record è il recordendfile che, se letto, provoca un salto ad una frase WRITE che scrive ilnumero dei records letti.
18.5 In una classe composta da n (~ 50) studenti vengono fatte mensilmentedelle prove scritte, una per materia, relative a 3 materie indicate con MAT l,MAT2 e MAT3. Scrivere:
a) un programma che aggiorni ogni mese, riportando i voti per ciascun
alunno, un file chiamato PROSCR, tenendo conto che il numero totale
dei mesi è 9. Gli alunni sono venti;
b) un programma che al termine delle prove fornisca le medie per alunno
relative a ciascuna materia.
c) un programma che fornisca l'elenco degli studenti che hanno conseguito
per ciascuna materia un voto medio maggiore o uguale a 6.
Esaminare le varie possibilità esistenti circa la strutturazione del file
PROSCR: sequenziale con e senza formato, ad accesso diretto con e senza
formato.
18.6 Trovare tutte le caratteristiche di un dato elenco di files.
18.7 Scrivere un sottoprogramma FUNCTION che realizzi l'arrotondamento di
un assegnato numero reale r ad un dato numero n di cifre significative. Ci
si deve servire di un file interno nella forma di variabile di tipo carattere dilunghezza 20. Si ottiene il voluto arrotondamento scrivendo il dato con ildescrittore Ew.n, con w opportuno.
4
APPENDICI
c
Al. Differenze con il subset language
I( subset language presenta, rispetto al fulllanguage F77, le seguenti limitazioni(cfr. [12]):
• I caratteri $ e : non fanno parte dell'alfabeto;
• Non sono ammesse più di 9 linee di continuazione;• Le frasi DATA devono seguire tutte le frasi di specificazione e precedere lefunzioni definite da una frase e le istruzioni eseguibili;
• Non sono permesse linee di commento tra le linee che costituiscono una istruzione;
• Non sono previsti dati di tipo doppia precisione e complesso;• Una variabile dimensionata non può avere più di tre dimensioni;• Un dichiaratore di dimensione può avere soltanto la forma SUPj;
• Un dichiaratore di dimensione deve essere o una costante o una variabileintera;
• Un'espressione indice può contenere soltanto costanti e variabili intere;• Non sono previsti gli operatori logici .EQV. ed .NEQV.;• Non sono previste le istruzioni: PRINT, CLOSE, INQUIRE, ENTRY,BLOCK DATA, PARAMETER, DOUBLE PRECISION e COMPLEX;• Soltanto nomi di blocchi COMMON possono far parte della lista di una istruzione SAVE;
• L'istruzione SAVE deve contenere sempre una lista;• Una lista con DO-implicito non può far parte di una istruzione DATA;
• Non sono permesse conversioni di tipo nelle frasi DATA;• La variabile del DO deve essere una variabile intera;
• I parametri del DO devono essere costanti intere oppure variabili intere;• Nell'istruzione GOTO-calcolato l'espressione deve essere una variabile intera;
• Non sono previste istruzioni di I/O guidate dalla lista;• Un identificatore di un file interno deve essere una variabile carattere o un elemento di variabile dimensionata carattere;
I •
"
382
• II numero di unità associato ad un file esterno non deve essere un'espressione;
• Un identificatore di formato deve essere l'etichetta di una frase FORMAToppure una costante carattere;
• Nelle istruzioni di 110 gli specificatori di unità edi formato non includono le
parole chiave UNIT = e FMT = :• Non sono previsti files ad accesso diretto con formato;
• Nelle istruzioni di 110 non è previsto lo specificatore ERR =:• Non sono previste le istruzioni di 110 della forma .READ f, lista-di-ingresso ePRINT f,lista-di-uscita;
• Nelle liste di IlO i parametri del DO-implicito devono essere costanti o variabiliintere. La variabile del DO-implicito deve essere di tipo intero;
• Le costanti, le espressioni ed i nomi di sottostringhe non possono comparirenella lista di uscita;
• L'istruzione OPEN è usata soltanto per specificare l'unità su cui effettuareoperazioni di 110 ad accesso diretto senza formato;
• Non è consentito l'uso di files esterni;• Non sono previsti i seguenti descrittori ripetibili: Iw.m, Dw.d, Gw.d, Gw.dEc;• Non sono previsti i seguenti descrittori non ripetibili: Tn, TLn, TRn, S, SP,SS,: ;
• In una specificazione di formato sono ammesse al più tre coppie di parentesiuna dentro l'altra;
• Non sono previsti «ritorni alternativi»;• Non esistono funzioni intrinseche che prevedono argomenti o risultati di tipodoppia precisione o complesso;
• Non sono previsti nomi generici per le funzioni intrinseche;
• Non sono previste FUNCTION di tipo carattere;• La specificazione della lunghezza di una entità di tipo carattere deve essere
fatta con una costante intera. Non è previsto lo specificatore (*);
• Non sono previste sottostringhe di caratteri;
• Non è prevista l'operazione di concatenazione;
• Non sono previste le funzioni intrinseche LEN, CHAR, INDEX;
• L'associazione di entità carattere effettuata per mezzo di istruzioni COMMONed EQUI VALENCE o attraverso gli argomenti di un sottoprogramma deve avveni
re tra entità della stessa lunghezza.
Le istruzioni che compongono ciascuna unità di programma devono seguire
l'ordinamento indicato nella seguente figura nella quale le linee orizzontali dividono gruppi di istruzioni che non possono .essere mescolate tra loro mentre quelle
verticali delimitano istruzioni che possono essere presenti contemporaneamentein qualsiasi ordine.
383
Istruzione iniziale: PROGRAM, FUNCTION, SUBROtITlNE
Istruzioni IMPLICIT
Altre istruzioni di specificazione
linee di commento Istruzioni FORMAT Istruzioni DATA
Funzioni definite da una frase
Istruzioni eseguibili
Istruzione END
Ordinamento delle i<ltruzionidel Subset Language in una unità di programma.
AZ. Principali differenzefra il FORTRAN 77 e il FORTRAN 66
Caratteri dell'alfabeto
• In F66 non esistono il carattere apice e il carattere due punti.
385
Espressioni aritmetiche
• In F66 le uniche espressioni miste consentite sono quelle tra operandi di tipo
reale e doppia precisione e tra operandi di tipo reale e complesso.
Espressioni logiche
• In F66 non esistono gli operatori .EQV. e .NEQV.
Espressioni carattere
• In F66 non sono previste espressioni di questo tipo.
Assegnazione aritmetica
• Nella frase di assegnazione v = e in F66 sono proibite le seguenti combinazioni
fra il tipo v ed il tipo di e:
v,k,v±k,s*v±k
Variabili dimensionate
Ricordiamo alcune caratteristiche delle variabili dimensionate in F66.
• Il massimo numero consentito di dimensioni è tre.
• Nel dichiaratore di variabile dimensionata è prevista, per ogni dimensione, la
dichiarazione della sola limitazione superiore, in quanto la limitazione inferiore è
uguale ad l.
• Non è previsto l'uso del dimensionamento indefinito.
• L'unica forma consentita di un dichiarato re di dimensione variabile è il nome
di una variabile intera, che deve far parte degli argomenti muti o di un blocco
COMMON nella stessa unità di programma.
• Ciascuna espressione indice nel nome di un elemento di variabile dimensionata
deve avere una delle forme seguenti:
Linee di commento
• In F66 una linea di commento è caratterizzata dalla presenza del carattere
C in colonna l. In F77 è possibile usare il carattere * e il carattere C.
Linee di continuazione
• In F66 sono consentite linee di continuazione che contengono qualsiasi carat
tere nelle colonne dalla prima alla quinta, eccettuato il carattere C sulla prima
colonna. In F77 le colonne dalla prima alla quinta di una linea di continuazione
devono contenere dei caratteri blank.
Nome del programma principale
• In F66 non è prevista la possibilità di dare un nome al programma principale;non esiste infatti l'istruzione PROGRAM.
Dati di tipo carattere
• In F66 non esiste il tipo carattere ma esistono le costanti di tipo Hollerith
ovvero costanti del tipo nH Cl c2 ... cn dove ogni Ci rappresenta un carattere.
Dichiarazione implicita di tipo
• In F66 non esiste l'istruzione IMPLICIT.
tipo di v
complesso
complesso
complesso
intero
reale
doppia precisione
tipo di e
intera (consentita in F77)
reale (consentita in F77)
doppia precisione (proibita anche in F77)
complessa (consentita in F77)
complessa (consentita in F77)
complessa (proibita anche in F77)
~ ~!
l''Il\
Nome simbolico di costante
• In F66 non esiste l'istruzione PARAMETER e quindi non esiste la possibilitàdi dare nomi simbolici alle costanti.
dove v è una variabile intera e k ed s sono costanti intere.
• Il valore di un indice nel nome di un elemento di variabile dimensionata puòsuperare la corrispondente limitazione superiore, purché la posizione di quel
l'elemento in memoria non superi l'ampiezza totale della variabile dimensionata
stessa.
386
• E' consentito usare in una frase EQUIVALENCE il nome di una variabile di
mensionata seguito da un solo indice, anche se le sue dimensioni sono più di una.
Istruzioni di controllo
• In F66 non esiste il costrutto IF-THEN-ELSE.
• La sola forma consentita per l'istruzione GOTO-calcolato è la seguente
GOTO (e l , ..., et), v
dove ciascuna ei è un'etichetta e v una variabile di tipo intero. Inoltre, a diffe
renza di quanto è previsto in F77, se il valore di v non è compreso fra l e k non
è stabilito quale istruzione debba essere eseguita dopo l'istruzione GOTO-calcolato.
• L'istruzione DO in F66 ha la forma seguente:
DO n v = mI' m2, m3
dove: n è l'etichetta del1a frase terminale; v, la variabile del DO, è di tipo
intero; mI' m2 e m3 sono il parametro iniziale, finale e d'incremento e possono
essere nella forma di costante o variabile di tipo intero. Il parametro m3, come
in F77, può essere omesso ed il suo valore in questo caso è assunto essere 1.
Devono inoltre valere le seguenti condizioni: mi' m2
, m3
> O e mi ~ m2. Al
termine de11'esecuzione del ciclo-DO la variabile di controllò è indefinita. Si os
servi che in F66 è permesso l'uso del rango esteso, proibito invece in F77.
Istruzioni di l/O
• In F66 non esistono le seguenti possibilità ed istruzioni:- Le istruzioni guidate dal1a lista;
- Il controllo del1e condizioni di errore e fine file;
- Le istruzioni OPEN, CLOSE e INQUIRE;
- I descrittori Iw.m, Ew.dEc, Gw.dEc, BN, BZ, S, SP, SS, :, Tn, TLn, TRn,'hl' .. hn ' ;
- Le operazioni di l/O ad accesso diretto.
• L'unica forma consentita in F66 per le frasi di l/O con formato è la seguente:
READ (u, f) lista
WRITE (u, f) lista
dove: u è una costante o variabile di tipo intero che identifica l'unità di l/O (solo
come file esterno); f ~ l'etichetta di una frase FORMAT o il nome di una variabile
dimensionata definita in modo tale da contenere dei caratteri costituenti una spe
cificazione di formato; la lista è costituita da eventuali liste con DO-implicito e
nomi di variabile, nomi di elementi di variabile dimensionata e nomi di variabile
dimensionata. In ogni caso la lista non deve contenere espressioni. Nel1e liste con
387
DO-implicito la specificazione v = mI' m2, m3 prevede che: v sia una variabile
di tipo intero; mI' m2, m3 siano variabili o costanti di tipo intero con le limitazioni già viste per l'istruzione DO.
• In una operazione di ingresso la definizione degli elementi della lista avviene
solo al completamento dell'esecuzione dell'intera operazione di lettura.
• Nelle operazioni di l/O con formato è possibile trasmettere sequenze di caratteri tramite il descrittore Aw. Tali sequenze possono essere associate ad elementi
della lista di l/O di tipo qualsiasi; la lunghezza massima di ogni sequenza è legata
al tipo dell'elemento ad essa associato nella lista di l/O.
• In F66 è possibile usare il descrittore n HCI ... cn in specificazioni di formato
associate ad istruzioni di ingresso.
• In F66 il descrittore Dw.d deve essere associato a dati di tipo doppia precisione
ed i descrittori Fw.d, Ew.d, GW.d a dati di tipo reale.
Sottoprogrammi
• In F66 non sono previsti ritorni alternativi dai sottoprogrammi.
• In F66 non sono previsti nomi generici, ma solo specifici, per le funzioni in
trinseche. Le seguenti funzioni intrinseche non esistono in F66: tutte le funzioni
che trattano dati di tipo carattere e DINT, ANINT, DNINT, NINT, IDNINT,
DDIM, DPROD, TAN, DTAN, ASIN, DASIN, ACOS, DACOS, SINH, DSINH,
COSH, DCOSH e DTANH. Non esiste, in F66, l'equivalente della funzione INT
applicata ad un argomento di tipo intero o complesso; analogamente non esiste
l'equivalente della REAL applicata ad un argomento di tipo reale; la funzione
CMPLX si applica solo ad una coppia di argomenti reali e la funzione DBLE si ap
plica solo ad un argomento reale. In F66 le funzioni AMOD, MOD, SIGN, ISIGN
e DSIGN non sono definite quando il valore del secondo argomento è zero.
• Le seguenti funzioni intrinseche in F66 non possono essere argomento attuale
corrispondente ad un argomento muto di tipo sottoprogramma: ABS, IABS,
DABS, AINT, INT, IDINT, AMOD, MOD, AMAXO, AMAXl, MAXO, MAXl,
DMAXl, AMINO, AMINl, MINO, MINI, DMINl, FLOAT, IFIX, SIGN, ISIGN,
DSIGN, DIM, 101M, SNGL, REAL, AIMAG. DBLE, CMPLX e CONJG.
• Le funzioni intrinseche usate come argomento attuale in corrispondenzaad un argomento muto di tipo sottoprogramma devono figurare in una frase
EXTERNAL; la frase INTRINSIC infatti, non esiste in F66. La frase EXTERNAL,
in F66, ha il solo scopo di dichiarare i nomi dei sottoprogrammi che figurano co
me argomenti attuali corrispondenti ad argomenti muti di tipo sottoprogramma.
• In F66 non esistono le istruzioni SAVE ed ENTRY.
Istruzione DATA
• In F66, nel1a forma nlista/vlista/ che figura in una frase DATA, nlista può
388
essere costituita solo da nomi di variabile e nomi di elementi di variabile dimensio
nata con indici nella forma di costanti intere.
Sottoprogrammi BLOCK DATA
• L'unica forma consentita, in F66, della prima istruzione di un sottoprogramma
BLOCK DATA è quella senza nome.
A3. Ordinamento delle istruzioni F77
Le istruzioni F77 possono essere raggruppate in:
l. Istruzioni iniziali: PROGRAMFUNcnONSUBROUTINEBLOCK DATA
2. Istruzioni di specificazione: IMPUCITPARAMETERINTEGERREALOOUBLEPRECISIONCOMPLEXLOGICALCHARACTERDIMENSIONEQUIVALENCECOMMONEXTERNALINTRINSICSAVE
3. Istruzione DATA
4. Funzioni definite da una frase
5. Istruzioni eseguibili: Assegnazione aritmetica, logica, carattere
Controllo: IF(c) THENELSE IFELSEENDIFIF-logicoIf'-aritmeticoGOTO - incondizionatoGOTO· calcolatoGOTO - assegnato (*)DOCONTINUESTOPPAUSE(*)END
Istruzione: CALL
Istruzione: ASSIGN (*)
(*) Questa istruzione non è stata trattata nel testo in quanto di scarsa utilità.
390 391
Ingresso/uscita: READ
WRITEPRINTOPENCLOSEINQUIREBACKSPACEENDFILEREWIND
6. Istruzione ENTRY
7. Istruzione FORMAT
8. Linee di commento
• La prima frase di ogni unità di programma deve essere una istruzione iniziale.L'istruzione PROGRAM può essere soltanto la frase iniziale del programma principale.
• L'ultima frase di ogni unità di programma deve essere un'istruzione END.
In un programma principale o in un sottoprogramma di tipo FUNCfION oSUBROUTINE le istruzioni devono rispettare iI seguente ordinamento:
• Tutte le istruzioni di specificazione devono precedere tutte le frasi DATA, lefunzioni definite da una frase e le istruzioni eseguibili;
• tutte le funzioni definite da una frase devono precedere tutte le istruzioni eseguibili;
• le frasi DATA possono comparire in qualsiasi punto dopo le istruzioni di specificazione;
• le istruzioni ENTRY possono comparire in qualsiasi punto che non sia dentroal rango di un DO o tra un'istruzione IF(c) THEN e la corrispondente istruzioneEND IF;
• le istruzioni FORMAT e le linee di commento possono comparire in qualsiasipunto.
Per le frasi di specificazione è inoltre fissato il seguente ordinamento:
• le istruzioni IMPLICIT devono precedere tutte le altre istruzioni di specificazione;
• ogni istruzione di specificazione che indica il tipo di un nome simbolico di costante deve precedere la frase PARAMETER che definisce quel particolare nomesimbolico di costante;
• la frase PARAMETER deve precedere tutte le altre istruzioni che contengonoi nomi simbolici di costanti da essa definiti.
Queste regole sono riassunte nella figura seguente nella quale le linee orizzontali
dividono gruppi di istruzioni che non possono essere mescolate mentre quelle
verticali delimitano istruzioni che possono essere presenti contemporaneamentein qualsiasi ordine.
Istruzione iniziale: PROGRAM, FUNCTION, SUBROUTINE,BLOCK DATA
Istruzioni IMPLICITIstruzioni
PARAMETERIstruzioni Altre istruzioni di specificazione
Linee di FORMATcommento ed
Istruzioni Funzioni definite da una fraseENTRY
DATAIstruzioni eseguibili
Istruzione END
Ordinamento delle istruzioni F77 in una unità di programma.
393
A4. La codifica dei caratteri64 blank 123 rI' 161 214 o6~74 124 @ 162 • 215 p
in ASCII e in EBCDIC75 . 125 163 t 216 Q
76 126 - 164 u 217 R77 ( 127 ..
165 21HZ4y
78 + 128 166 w 22579 I 129 • 167 )( 226 S80 & 130 b 168 v 227 T
81-89 131 c 169 z 228 U
90 ! 132 d 170-191 229 V91 I 133 e 192 230 W92 * 134 f 193 A 231 X93 135 g 194 B 232 y
94 136 h 195 C 233 Z
Codice ASCII 95 137 1 196 O 231r-Z3996 - 13&-144 197 E 240 O
Il codice ASCII definisce 128 caratteri utilizzando per ciascuno 7 bits. I carat- 97 I 145 j 198 F 241 1
teri riproducibili in stampa sono i seguenti: 9&-106 146 k 199 G 242 2107 , 147 l 200 H 243 3108 l 148 Il 201 I 244 "109 149 n 202-208 245 5
32 blank 56 8 80 P 104 h 110 150 209 J 246 6> o 247 7
33 ! 57 9 81 Q 105 111 ? 151 p 210 K 248 834 .. 58 82 R 106 j 112-120 152 211 L 249 9q35 " 59 83 S 107 k 121 153 r 212 ..36 S 60 < 84 T 108 l 122 154--160 213 N
37 X 61 . 85 U 109 Il
38 & 62 > 86 V 110 n
Il39 63 ? 87 W 111 o Nelle tabelle riportate i numeri decimali che accompagnano ciascun carattere40 64 @ 88 X 112 p sono i corrispondenti numeri d'ordine.41 65 A 89 y 113 q42 * 66 B 90 Z 114 r43 + 67 C 91 [ 115 s44 , 68 D 92 \ 116 t45 - 69 E 93 J 117 u46 70 F 94 118 v47 I 71 G 95 119 w48 O 72 H 96 120 x49 1 73 I 97 a 121 y50 2 74 J 98 b 122 z51 3 75 K 99 c 123 {52 4 76 L 100 d 124 I53 5 77 .. 101 e 125 l54 6 78 N 102 f 12655 7 79 O 103 9
Codice EBCOIC
Il codice EBCOIC utilizza 8 bits per la codifica di ciascun carattere; esso comprende tutti i caratteri del codice ASCII ordinati però in modo diverso.
•
Bibliografia
(1] DAHL O.J., HOARE C.A.R., DIJKSTRA E.W. (1972): Structured Programming, AcademicPress, New York.
[2] CHURCH A. (l956):Introduetion to mathematicallogic I, Princeton UnivoPresso
[3] ANDRONICO A. ed altri (1973): Scienza degli elaboratori, Zanichelli, Bologna.
[4] WINSTON D., HORN B.K.P. (198 I): L/SP, Addison Wesley.
[5] NAUR P. (1963): Revised report on the Algorithmic LanguageAIgol60, Comm. ACM voI.6, n. 1.
[6] LECARME O., NEBUT J.L. (1985): Pascal - Guida per programmatori, McGraw-Hill.
(7] Mc CARTHY J. (1963): A basis for a mathematical theory of computation, Proc. IFIPCongress 1962, North-Holland Pub. Co., Amsterdam.
[8] HERMES H. (1955): Entscheidungsprobleme in Mathematik und Logik, Ausarbeitungeiner Vorlesung, Aschendorft, Mtinster i.w.
[9] FONTANELLA F., PASQUALI A. (1979): Calcolo numerico. Metodi ed algoritmi, PitagoraEd., Bologna.
(10] FORSYTHE G.E., MALCOLM M.A., MOLER C.B. (1977): Computer methods for Mathematical Computations, Prentice-Hall, Englewood Cliffs.
[II] FORSYTHE G.E., MOLER C.B. (1967): Computer Solution of Linear Algebraic Systems,Prentìce-Hall, Englewood Cliffs.
(12] ANSI X3.9·1978 - American National Standards Inst. NewYork.
[13] ANSI X3.9-1966 - American National Standards Inst. New York.
[14] GoLUB G.H., VAN LoAN C.F. (1983): Matrix computations, John Hopkins Univo Presso
[15] MEYER B., BAUDOIN C. (1978): Méthodes de programmation, Eyrolles.
Indice analitico
I numeri in neretto si riferiscono alle Appendici.
A, 195, 204,209ACCESS =. 360, 362, 369, 371Accesso, vedi: fileAccumulatore, 23Albero delle chiamate, 240,347Alfabeto, 48, 185Algoritmo, 3, 239, 245, 252Allungamento, 181, 185
vedi: blocco COMMONAmpiezza
argomento, 279, 288campo, 194,204dimensione, 153, 288variabile dimensionata, 153, 160
.AND.,78Annidamento
ciclo-DO, 145DO-implicito, 221struttura decisionale, 105
Apice, 48, 92, 174, 196, 205, 2I7, 384Apostrofo, 174Argomento, 73,187,189,312
vedi: ampiezza, lista, lunghezza, ordineasterisco, 245, 298attu~e,243,249,256,260,275, 288,293,298,307,333,336,340carattere, 289costante, 276di ingresso, 243, 250di uscita, 243, 250, 276espressione, 74, 276muto, 243,245, 249, 253, 256, 259, 275, 288,307,316,322, 331,341,384funzione intrinseca, 298, 387sottoprogramma, 245, 249, 253, 256, 292,387variabile, 245, 249, 253, 256variabile dimensionata, 245, 249, 253, 256, 277
Aritmeticavedi: assegnazione, espressione
if'l-I
; I
398
finita, 41intera, 68, 138, 268reale, 68, 138
Arrotondamento, 39, 201, 263, 265vedi: esempi
ASCII, 173,185,268,392Assegnazione, 3, 83, 90,157,180,184,260,291,323,372
aritmetica, 83, 322, 385, 389carattere, 180,204,322,389logica, 83, 86, 389mista, 85simbolo, IO, 83
Assemblatore, 26ASSIGN,389Associazione, 243, 250, 260,276,292,307,31 IAsterisco, 48,50,61,197,205,228,382
vedi: DATA, dimensionamento indefinito, identificatore di formato, lunghezza indefinita,PRINT*, READ*, ritorno alternativo
Attivazioneciclo-DO, 128, 140sottoprograrnma, 241, 249, 257, 275, 289, 307, 336, 339, 347
Aw, 195,203.209,387
BACKSPACE, 355,366, 390Base di numerazione, 33, 37Bit, 22, 173Blank,48, 174, 18~ 376,384
vedi: A, Aw, BLANK =, BN, BZ, Gw.d, nX, READ *,spaziatura, TnBLANK = ,360, 363, 372Blocco COMMON, 280, 288, 307,309,312,319,341,381,384
vedi: COMMON, lunghezzaallungamento, 319etichettato, 307, 310, 322, 325, 347indefinito, 347nome,307,310,348,381non etichettato, 308, 311, 322, 347
Blocco ELSE, 103,116Blocco THEN, 103BLOCK DATA, 243, 293, 322, 325, 381,387,389BN, 196,231,363,386Byte, 22, 35, 354BZ,196,231,363,386
CALL, 249, 335, 389Campo, 194,209,228,233,358,363
vedi: ampiezzaCarattere
vedi: A, Aw, argomento, assegnazione, CHARACTER, costante, espressione, funzione
399
esterna, ingresso/uscita, lunghezza, ordine, unità di memoria, variabilecodificabile, 173, 185, 189, 392iniziale e finale. vedi: esempispeciale, 48tipo, 173,308,337,382,384
Caratteristica, 37, 40,201,228Caricamento. 24Cella. vedi: locazioneCHAR, 189,268,382CHARACTER, 57, 174,253,337,389Chiamata, 240, 275
ricorsiva, 14,277Ciclo, 125
vedi: annidamento, DO, UNTIL, WHILEfinito, 127, 131iterativo, 12, 128, 131, vedi: esempi
CLOSE,364,38],386,390Codice operativo, 23Colonna, 50, 384Commento, 50,38],384,390COMMON 307, 316, 319, 325, 332,382,389Compilatore, 26, 57,153,162,277,312Compilazione, 26, 244, 275, 321,325Complemento a due, 36Complesso
vedi: assegnazione mista, COMPLEX, costante, descrittore, espressione mista, ingresso/uscita,operazione
COMPLEX, 57, 253,38],389Concatenazione, I Il,179,208,291,382Conne~ione, 10,359,361,364,373Contatore
vedi: DO, ripetizioneContinuazione, 5 I , 38] , 384CONTINUE, 119, 129,136,146,389Controllo
vedi: istruzione, lista, spaziatura, trasferimento del controllo, unitàConversione, 33, 37, 71, 75, 197,317, 322,358
vedi: funzione intrinsecaCorpo
vedi: ciclo iteratìvo, sottoprogrammaCoUank,4~53.90,96,276,321,323,382
vedi: argomento, dimensionamento, espressione, PARAMETERcarattere, 56,92, 174, 205, 216, 289, 382complessa, 55, 202doppia precisione, 55, 199intera, 53, 153,156,174,198,230,233logica, 56nome, 54,96, 153, 174, 176, 258,321,384,390reale, 54, 199
400
D,55,201DATA, 321, 323, 325,381,387,389'DELETE', 365Descrittore non ripetibile, 195,202,210,215,218,231,382
di tabulazione, 230Descrittore ripetibile, 195,209,212,228,233,358,382
carattere, vedi: A, Awcomplesso, 202intero, vedi: Iw, IW.mlogico, vedi: Lwreale, 199,202,209,228, vedi: Dw.d, Ew.d, Ew.dEc, Fw.d, Gw.d, GW.dEc
Diagnostico, 26, 28Diagramma, 9, 12Dichiarativa
vedi: istruzioneDichiaratore
dimensione, 153, 160, 280, 288, 381dimensione indefinita, 288dimensione variabile, 280, 288, 385variabile dimensionata, 153, 160, 308, 332, 385
DlMENSION, 155,389Dimensionamento
costante, 153, 308indefinito, 288, 385variabile, 280, 285, 288, 313,332
Dimensione, 156, 167,278vedi: ampiezza, dichiaratore
'maser', 362, 368, 373DlRECT =, 372D~c~ 22,351,360,368dnr, 195, vedi: descrittore non ripetibileDO, 128, 132, 141,333,381,386,389
vedi: annidamento, DO-implicitociclo, 133, 138, 145contatore, 127, 133, 135, 220frase terminale, 132, 136,145,147,333parametro, 133,381,382rango, 133, 135, 137, 141, 145,220,390variabile, 133, 136, 143,145,381
DO-implicito, 219, 321, 323, 381,382,386Dollaro, 48Doppia precisione
vedi: assegnazione mista, costante, descrittore ripetibile, DOUBLE PRECISI0N, espressionemista, ingresso/uscita, precisione
DOS, 31, 369DOUBLE PRECISION, 57, 253,381,389dr, 195, vedi: descrittore ripetibileDue punti, 48, 231, 381, 384, 386
vedi: dichiaratore di variabile dimensionata, sottostringaDw.d, 195, 199,201,209,233,382,386
E,54, 201,228EBCOIC, 173,392Elemento di variabile dimensionata, 151,160,178,279,289,355,375,385
nome, 156,277,292,316,321,357,364posizione, 160
Elevamento a potenza, 67ELSE, 102, 105, 112, 114, 136, 142,389
vedi: blocco ELSEELSEIF,112,114,136,141,389END,93,136,206,244,321,325,389ENDFILE, 354, 390END IF, 102, 105, 112, 114, 136, 142,333,389,390END =,355,357,386ENTRY, 331, 336, 338,341,381,387,390.EQ., 76,185Equazione di 2° grado, vedi: esempiEQUIVALENCE, 316, 325, 374,382,386,389.EQV., 78, 381,384Errore
arrotondamento, 40, 169,248assoluto, 40condizione di, vedi: ERR =programmazione, 28,58, 131, 275relativo, 40
ERR =, 354, 357, 360, 363,365,372,374,382,386Esecuzione, 83, 101,208,210,212,223,245,257,260,275,298,307,331,339
vedi: programmaEsempi
arrotondamento, 377carattere iniziale e finale, 289ciclo itera tivo, 12, 129equazione di 2° grado, 107,247,252fattoriale, 17,254,257massimo e minimo, 4,7,15,116,119,246,252,281media aritmetica, 125, 136, 142,145,168,239norma,282,295,338,340ordinamento, 110,115,166,313polinorrUo, 163,334,336precisione di macchina, 255prodotto, 6,15,138prodotto scalare, 167, 169radice quadrata, 129, 131, 144,246,251simulazione della ricorsività, 344somma, 6, 14, 16,23,25,137,278
Esponente, 54,67,92,199,233Espressione, 61,83,91, 157,259,276,382,386
aritmetica, 61, 76,83,120,133,153,385carattere, 179, 184, 189,205,207,289,360costante, 79,96, 174, 258, 316,321,324, 363, 365,385di sottostringa, 179, 321
401
402
indice, 156,160,321, 381, 384intera, 223, 280, 298, 354, 356, 359, 362,369logica, 77, 103, 112, 116,385mista, 70,384relazionale, 76, 185valutazione, 62, 69, 74, 76, 78
Etichett~25,49, 51,101,103, 120, 13~ 205, 299,307,358,364Ew.d, 195, 199,201,209,233,387Ew.dEc, 195, 209, 228, 233,386EXIST =, 372EXTERNAL, 292, 333, 387,389
Fattore di scala, vedi: sPFattoriale, vedi: esempiFile, 222, 351, 359
accesso diretto, 352, 362, 367, 371, 373, 382,386con formato, 362connesso, 359, 364; 372esterno, 222, 352, 356, 358, 371, 381, 382fine, vedi: ENDFILE, END =, recordinterno, 352, 356, 358, 375, 381nome, 360, 372preconnesso, 359, 364senza formato, 362sconnesso, 364sequenziale, 222,351,356,362,365,373stato del, 361
FILE =, 360,371,374Floating point, 37, 70, 264f1(x), 39Floppy disk, 22, 368Flusso, 3,101,242
diagramma di, 12FMT =, 355, 356, 382FORM =, 360, 362,371FORMAT, 205, 382, 386, 390Formato, 92
vedi: file, identificatore di formato, record, specifìcatore, specificazionedella linea, 50
'FORMATTED', 362, 373FORMATTED =, 372Frase, vedi: istruzioneFull language, 47,381FUNCTION, 243, 253, 293, 337,339,389Funzione definita da una frase, 259, 389, 390Funzione esterna, 252, 340
vedi: FUNCTION, lunghezzacarattere, 258, 382nome, 253,256,338
prima istruzione, vedi: FUNCTIONriferimento, 256tipo, 253, 256, 337valore, 252, 337
Funzione intrinseca, 71, 261, 293,382vedi: argomentoconver~one, 262, 298manipolazione dei caratteri, 187,267,298,387matematiche, 265altre, 268nome, 262,265,298,382
Funzione ricorsiva, 14,344Fw.d, 199,200,209, 233,387
.GE., 76, 185GOTO-assegnato, 136,389GOTO-calcolato, 120, 381, 386, 389GOTO-incondizionato, 101, 121, 129, 136,389.GT., 76,185Gw.d, 195,209,229,382,387Gw.dEc, vedi: GW.d
H, vedi: n H h I ... hnHardware, 21Hollerith, 384'hl' .. hn ' , vedi: n H hl ... hn
ICHAR, 189,268Identificatore di formato, 205, 217, 223, 356,381IF-aritmetico, 121, 136, 389IF-Iogico, 117, 119, 129,389IF-THEN-ELSE, 102, 119, 136,140,333,386,389,390IMPLICIT, 58, 177,254,325,384,389,390Incremento, 134Indentation, 107INDEX, 188, 268, 382Indice, 152, 156, 160, 165, 286, 316, 384
vedi: espressioneIndirizzo, 23,275, 278, 289, 292,307
assoluto, 28relativo, 26
Inf j : sUPi, 153Ingresso/uscita
vedi: istruzione, lista, operazione, simbolo, unitàdati carattere, 183, 203, 209dati complessi, 202dati interi, 198, 209
403
404
dati logici, 230dati reali e doppia precisione, 199,202,209,386guidata dalla lista, 90, 183, 193, 202, 204, 224, 381,386variabile dimensionata, 164, 167
INQUlRE, 371,374,381,386,390INTEGER, 57, 253,389Intero
vedi: aritmetica, costante, espressione, ingresso/uscita, INTEGER, Iw, lw.m, rappresentazioneInterpretatore, 18, 29INTRINSIC, 298, 387, 38910STAT =, 354,357,360,363,372,374Istruzione, 3, 23,48,51
vedi: ordineassegnazione, 3, 291, 323controllo, 386, 389dichiarativa, 49,57,244,277,280,321,389,390dichiarativa di tipo, 154, 174,253,325,337dipendente, 116eseguibile, 49, 389,390finale, vedi: istruzione terminaleingresso/uscita, 89,193,205,222,351,355,381,386,389iniziale, 103, 105, 141,242,389,390posizionamento, 366ritorno, 242specificazione, vedi: istruzione dichiarativaterminale, 103, 105, 112, vedi: DO
lw, 195,198,209lw.m, 195,209,228,382,386
'KEEP', 365
.LE., 76,185LEN, 190,268, 382LGE, 187,268,298LGT, 187,268,298Linea, 50,90,92
vedi: commento, continuazioneLinguaggio, 21, 23, 25, 31Linker, 28, 222, 312, 359Lista
vedi: DO-implicitoargomenti, 250, 256, 275, 280, 288, 292, 298, 312,322, 331controllo, 355, 358, 369ingresso/uscita, 90, 157, 164, 183, 197,205,208,212,214,218,222,256,354,358,
371,382,386,387programma, 50
LLE, 187, 268, 298LLT, 187,268,298
s
405
Locazione, 22, 83,151,160,163,253,275,310,339LOGICAL, 57, 253,389Logico
vedi: costante, espressione, ingresso/uscita, LOGICAL, Lw, operatore.LT., 76, 185Lunghezza
vedi: specificatoreargomento, 289blocco COMMON, 309, 320complessiva, 292dato carattere, 173, 178, 268, 382funzione esterna, 258indefinita, 176,258,290,337record,21~353,362,369,371,373,376
sottostringa, 179Lw, 195,209,230
Mantissa, 37,40,201Massimo o minimo, 268, 298
vedi: esempiMatrice, 152, 154, 161,286Media aritmetica, vedi: esempiMemoria, 22,351,365,375Modulo oggetto, 28Monoprogrammazione, 31Multiprogrammazione,31
NAME =, 372NAMED =, 372Nastro, 22, 351, 360.NE., 76, 185.NEQV., 78, 381, 384NEXTREC =, 372, 374'NEW', 361nHh\ ... hn, 196,216,387Nido, 105'NO', 373Nome
vedi: costante, elemento di v. dimensionata, file, funzione esterna, funzione intrinseca,programma, punto di ingresso secondario, sottoprogramma, sottostringa, variabile,variabile dimensionata
generico, 262, 265, 298, 382,387locale, 244,310simbolico, 25,49,59,151, 174,239,245,253,259,298,307,323,325,331,341specifico, 262, 265, 298, 387
Norma, vedi: esempi.NOT.,78'NULL', 363,373
\ I
406
NUMBER =, 372nX, 196,215,230
'OlD: 361. 363OPEN,222,353,358,365,382,386,390OPENED =, 372.OR.,78Operatore
aritmetico, 61concatenazione, 179logico, 77priorità, 62, 71, 78relazione, 76, 185
Operazionel'cdi: ordinecomplessa, 70conversione, 71, 73elemen tare, 41ingresso/uscita, 89, 209,231,256,351,355,387primitiva, 3simbolo, 9
Ordinamento, vedi: esempiOrdine
argomenti, 250, 256, 336caratteri, 185istruzioni, 49, 383, 389, 391operazioni, 62, 64, 69
Overtlow, 35, 39, 54,68, 138. 254
P, vedi: sPPARAMETFR, 96,176,258,323,325,38],384,389,390Parametro. vedi: argomento. DOParentesi, 48. 64,73,78. 174, 195, 210,219,245,253,333,336,340,382Parola chiave, 49PAUSE,389Preconnessione, 359.364Polinomio, vedi: esempiPrecisione
di macchina, 40, 92, 130, 255doppia, 41, 169,200,202.264finita, 130semplice, 41,169,200.264
Predefinizione, 322PRINT,256,381,390PRINT r, 205, 223,382PRINT·,91.223,289Prodotto, 269, vedi: esempi
scalare, vedi: esempi
407
PROGRAM, 93, 384, 389, 390Programma, 21, 89, 239, 275, 307,311,325,359
vedi: lista, unitàesecuzione, 28, 241, 310, 323, 341, 347.363eseguibile, 28, 241nome,93,384 .oggetto, 26, 28princip~e,239, 241,307,347,384,390sorgente, 26
Punto di ingresso secondario, 331vedi: ENTRYnome, 332,336,339riferimento, 335, 340tipo, 337
Punto di riscansione, 210
Radice quadrata, vedi: esempiRango, vedi: DORappresentazione, 33
esterna, 197, 201, 203, 229, 232, 353finita, 39, 70interna, 197,200,202,262,352
READ, 355, 390READ f, 205, 223, 382READ (u, f), 222,386RE AD. , 90, 205, 223REAl, 57, 75, 253,389Reale
vedi: aritmetica, costante, descrittore ripetibile, espressione, ingresso/uscita, rappresentazioneREe =, 355, 359, 369RECl =,360,362,369,372Record, 194, 197,201,212,222,351,366
vedi: lunghezzacon formato, 352, 362, 371corrente, 209,212,214,218,230end fik.352,354,35~366
numero d'ordine, 369senza formato, 352,362,371, 373
RETURN, 136, 244, 298REWIND, 355, 365, 390Ricorsività, 14, vedi: esempiRipetizione, 125, 130, 133,220,324
contatore, 127. 134. 195simbolo, 9
Ritorno alternativo, 249, 298. 301, 382, 387
S, 196,232,382,386SAVE, 325,341,348,38],387,389
408
Sbarra, 48vedi: COMMON, concatenazione, descrittore non ripetibile, operatore, READ., SAVE
Scambio, 87di informazioni, 243,275,313,331,341
'SCRATCH', 361, 365'SEQUENTIAL', 362, 373SEQUENTIAL =, 372sf, 195, vedi: specificazione di formatoSimbolo, ':J
tavola, 26, 322Software, 21Somma, vedi: esempiSottoprogramma, 239, 275, 292, 307, 331, 387, 390
vedi: argomento, attivazione, BLOCK DATA, funzione esterna, funzione intrinseca, puntodi ingresso secondario, SUBROUTINE
chiamata, vedi: attivazionecorpo, 243, 253,280,288,325,331,333esterno, 292nome, 73, 243, 249, 253,256,292prima fase, 242, 332uscita, 241
Sottostringa, 178,180,182,207,289,355,375,382vedi,' espressione, lunghezzanome, 179,292,316,321
SP,196,232,382,386sP, 196,233Spaziatura
l'cdi: blankverticale, 214
Specificatoreformato, 356lunghezza, 174, 177lunghezza indefinita, 176, 258, 290, 337ritorno alternativo, 249, 299stato, vedi: 10STAT =, STATUS =tipo, vedi: CHARACTER, COMPLEX, DOUBLE PRECISION, INTEGER, LOGICAL,
REALunità, vedi: UNIT =
Specificazionevedi: istruzioneformato, 194,205,208,212,214,224,232,354,358,363,371,382formato variabile, 208, 226vuota, 214
SS,196,232,382,386Stampante, 92,214,351,360STATUS =, 360, 365
. STOP, 93,136,242,244,389Stringa, 173, 180,182,185,188,203,217,289
vedi: lunghezza dato carattereStruttura decisionale, 102, 105, 111, 114, 140
409
vedi: annidamento, IF-THEN-ELSEStruttura di ripetizione, 125
vedi: DOSUBROUTlNE, 243, 245, 292, 298, 334, 389
vedi: CALLSubset language, 47,381sup], 153,381,384Supervisore,31
Tavola dei simboli, 26,322Testina di lettura/scrittura, 352, 365, 368Time-sharing, 31Tipo implicito, 58, 177,254,384
vedi: IMPLICITTLn,196,230,382,386Tn,196,230,382,386Tolleranza, 77, 131Traduttore, 18, 25Traduzione, 28Trasferimento del controllo, 101,104,137,143,147,242,299,331TRn,196,230,382,386Troncamento,39, 181,263
Underf1ow, 39, 54'UNFORMA TTED', 362, 373UNFORMATTED =, 372UNIT =, 354,360,365, 371,382Unità
aritmetica, 22attivante, 241, 243, 250, 258, 275, 288, 292, 299, 307,331,333,341,347di controllo, 22di ingresso/uscita, 22, 89,210,212,222,351,354,359,364,371,375di memoria carattere, 173, 182,289, 292, 307,310di memoria numerica, 22, 307, 310di programma, 21, 239, 242, 260, 275,293,298,307,309,311,316,319,358,364,
383,390numero di, 222, 354, 373, 381
'UNKNOWN', 361, 373UNTlL,128
Variabile, 56vedi: DO, DO-implicitocarattere, 174,289,356,375interna, 341, 348nome di, 56,83,245, 249,253,256,275,280,308,316,321,342,357,364tipo, 56,275
Variabile dimensionata, 151, 153, 156
I:l
Ii
II
I I
410
vedi: ampiezza, argomento, dichiaratore, elementonome, 153, 155, 164, 178,205,208,245,249,253,256,298,308,316,321,342
Vettore, 152, 154, 160Video, 92, 351Virgola, 48, 73,90,120, 133,218,231,308,316,321,348,354
l'cdi: floating point
WHILE,128WRITE, 256,355,390WRITE (u, f), 222, 386
X, vedi: nX
'YES',373
'ZERO', 363. 373