Visualizzazioni Totali

TRA I PRIMI IN ITALIA A PARLARE DI BITCOIN (DAL 2012!): PER ESSERE SEMPRE AGGIORNATI SULLE NOVITA' TECNOLOGICHE DEL WEB SEGUITE LA PAGINA FACEBOOK (LINK A SINISTRA)

venerdì 26 gennaio 2018

Guida Al Fortran: Variabili, Array, Costanti, Operazioni, Comandi Di Controllo

Essendo stato sviluppato nel 1954, il Fortran fu uno dei primi linguaggi di programmazione. Seppur concettualmente datato, oggi, è ancora molto utilizzato in ambito scientifico. Venne ideato principalmente per scrivere software che eseguivano calcoli matematici. Nel tempo sono comparse moltissime versioni, sino al Fortran 2008. Qui si parlerà principalmente del Fortran 77, dando alcune nozioni di base, del resto con un articolo è assolutamente impossibile parlare di un programma vasto come il Fortran (che dalla sua nascita ha anche subito più modifiche come visto).
Per tutto il resto si rimanda a corsi specifici o libri di testo ("Come programmare con il Fortran" Coen, 1969. "Uno strumento per il calcolo scientifico", "Fortran 77: manuale di riferimento" Fornaro, 1998", "Il linguaggio Fortran").


NOZIONI DI BASE
I programmi scritti in un linguaggio di programmazione ad alto livello devono essere tradotti nel loro
equivalente in linguaggio macchina per poter essere eseguiti. Esistono due modalità per la traduzione di un programma in linguaggio macchina: l’interpretazione e la compilazione. Nel primo caso la traduzione e l’esecuzione vanno di pari passo: un interprete traduce un’istruzione per volta e, in assenza di errori, la esegue immediatamente. Nel secondo caso un compilatore traduce tutto il programma, generando un programma in linguaggio macchina equivalente a quello originale, che può essere conservato in memoria. La compilazione talvolta prevede due passaggi: prima il programma viene tradotto in linguaggio assembly e poi l’assembler traduce in linguaggio macchina.
Sia gli interpreti che i compilatori sono a loro volta programmi, spesso originariamente scritti in un linguaggio di programmazione, tradotti in linguaggio macchina e definitivamente memorizzati sul computer. Con il termine implementazione, di un programma scritto in Fortran si intende la sequenza di operazioni da svolgere per arrivare all’esecuzione del programma (in base alla sua funzione).
Per questo linguaggio di programmazione, le operazioni da svolgere sono due: compilazione e collegamento. Compilatori ed interpreti: CompilersDal sito ufficiale: G95 Fortran (Windows)


ESEMPIO PROGRAMMA AREA
C Programma che calcola l’area di uno o più triangoli
C usando la formula dell'area

Area Program
REAL A,B,C,SP,AREA
INTEGER LEGGI
10 PRINT∗, ’immettere le lunghezze dei lati’
READ∗, A,B,C
SP=(A+B+C)/2.
AREA=SQRT(SP∗(SP-A)∗(SP-B)∗(SP-C))
PRINT∗,’area= ’, AREA
PRINT∗,’ancora? (1/0= si/no)’
READ∗,LEGGI
IF(LEGGI.EQ.1) GOTO 10
STOP
END

Lo scopo del programma è calcolare l’area di uno o più triangoli con la formula

ps(s − a)(s − b)(s − c)

dove a, b, e c sono le lunghezze dei lati e s e il semiperimetro.
Nel programma usiamo i nomi A,B e C per a, b e c e SP per s.

– L’istruzione PROGRAM AREA dà il nome al programma;
– Le istruzioni REAL A, B, C, SP, AREA (sono variabili) e INTEGER LEGGI mettono in evidenza che A,B,C,SP e AREA rappresentano grandezze a valori reali, mentre LEGGI identifica una grandezza a valori interi (integer). I reali sono del tipo 1.0, invece gli interi senza decimali.
-SQRT è la radice quadrata
Qui finisce la sezione DICHIARATIVA.

– Le istruzioni caratterizzate dalla parola chiave PRINT∗, sono istruzioni di scrittura a schermo: le stringhe racchiuse fra apici (come ‘immettere le lunghezze dei lati’) vengono trascritte su schermo, mentre delle variabili come AREA viene stampato il valore.
Questa è la sezione ESECUTIVA.

– Le istruzioni caratterizzate dalla parola chiave READ∗, sono istruzioni di lettura: i dati vengono scritti sulla tastiera separati da virgole o spazi bianchi, su una o più righe;
– L’istruzione IF (LEGGI.EQ.1) GOTO 10 realizza una situazione di scelta: se il valore della variabile LEGGI è uguale a 1, viene eseguita l’istruzione GOTO 10, per effetto della quale l’esecuzione del programma riprende dall’istruzione 10 PRINT∗, ’immettere le lunghezze dei lati’; altrimenti l’esecuzione prosegue con la successiva istruzione STOP che fa fermare il programma.
Ovvero, dopo aver calcolato l’area di un triangolo, il programma chiede se si deve continuare; in caso affermativo, si leggono le lunghezze dei lati di un nuovo triangolo, altrimenti ci si ferma.
– L’istruzione END che indica la fine del programma.


STRUTTURA
Dunque, ricapitolando, abbiamo:
1) Sezione dichiarativa
E' posizionata all’inizio e contiene istruzioni non eseguibili quali: nome del programma preceduto dal testo program; dichiarazione delle variabili.
2) Sezione esecutiva
Rappresenta il corpo del programma e contiene le istruzioni eseguibili necessarie per effettuare le operazioni per le quali il programma stesso è stato ideato.
3) Sezione conclusiva
Contiene le istruzioni che interrompono il programma quali:
-stop che interrompe il programma in esecuzione
-end program dice al compilatore che il programma è terminato in fase di compilazione


DICHIARAZIONI DI VARIABILI, VETTORI, FUNZIONI MATEMATICHE, OPERATORI, ISTRUZIONI
Variabili (valori di default)
1) Iniziali con lettere da I a N sono variabili intere, 4 byte in precisione singola
2) Iniziali con lettere da A a H oppure da O a Z sono variabili reali, 4 byte in precisione singola


Variabili scalari (definizioni)
Abbiamo 5 tipi di variabili:
INTEGER A La variabile A è definita intera.
Aggiungere *8 o *16 dopo INTEGER per la precisione doppia o quadrupla.
REAL A La variabile A è definita reale.
Aggiungere *8 o *16 dopo REAL per la precisione doppia o quadrupla.
COMPLEX A La variabile A è definita complessa.
Aggiungere *16 COMPLEX per la precisione doppia.
CHARACTER*N A La variabile A è definita come una variabile stringa.
La lunghezza in byte della stringa e' data dal numero intero N.
LOGICAL A La variabile A e' definita come una variabile logica che può assumere solo due valori TRUE o FALSE
A=.TRUE.
A=.FALSE

Spieghiamo un po' di termini: “integer” and “real” hanno lo stesso significato per le variabili e per numeri.

Regole per la definizione delle variabili:
-Il primo carattere di una variabile deve essere una lettera.
-I caratteri seguenti possono essere una combinazione di caratteri e numeri.
-Non sono ammessi caratteri speciali.
-Non si possono usare più di 6 caratteri per ogni nome di variabile.
-Gli spazi vuoti non sono ammessi.
-Se non esplicitamente dichiarato le variabili il cui nome inizia con le lettere I, J, K, L, M, or N sono
dichiarate come integer mentre le variabili real sono quelle che iniziano con una delle rimanenti lettere.
-Un singolo nome deve essere utilizzato per ogni variabile.
-Prima che una variabile possa essere usata in un calcolo deve essere inizializzata!
-I comandi Fortran non possono essere usati come nomi di variabili (READ, WRITE, STOP, etc.)


Variabili dimensionate (Array): vettori e matrici
Per le grandezze scalari, il compilatore associa una locazione di memoria ma se abbiamo a che fare con vettori e matrici o con variabili a tre o più dimensioni (massimo 7)?
Per questi motivi sono state introdotte le variabili dimensionate (il termine tecnico è array).
Useremo un'istruzione dichiarativa, caratterizzata dalla parola chiave DIMENSION, tramite la quale si danno al compilatore tutte le informazioni necessarie per allocare la memoria e tradurre poi nel modo corretto le istruzioni eseguibili che coinvolgono elementi dell’array.

DIMENSION A(N1),B(N2,N3)
Le variabili A e B sono definite come vettori di dimensioni N1 e N2 x N3 rispettivamente.

DIMENSION Y(3),M(4,2)
Essa dice al compilatore che Y è un vettore composto da 3 elementi e M è una matrice di 4 righe e 2 colonne. Il compilatore assegna a Y tre locazioni di memoria consecutive in cui sono memorizzati gli elementi di Y: nella prima c’è l’elemento di indice 1, nella seconda quello di indice 2 e nella terza quello di indice 3. Per la matrice M il compilatore riserva invece 8 locazioni di memoria consecutive, nelle quali dobbiamo immaginare la matrice memorizzata per colonne, come descritto nello schema seguente:

locazione: 1 2 3 4 5 6 7 8
indici: (1,1) (2,1) (3,1) (4,1) (1,2) (2,2) (3,2) (4,2)

In assenza di dichiarazioni, Y è un vettore reale e M è una matrice intera, con il che si intende che tutti gli elementi di Y sono reali e tutti gli elementi di M sono interi.
Se si deve creare un vettore in cui memorizzare quanti abitanti di un paese sono nati negli anni dal 1995 al 2012, può essere comodo usare gli indici da 1995 a 2012 invece che da 1 a n.
In Fortran è possibile dire al compilatore che gli indici non partono da 1, esprimendo esplicitamente nella dichiarazione dell’array il primo e l’ultimo valore che l’indice può assumere.

Ad esempio
INTEGER ABITANTI(1995:2012)

Di fronte a dichiarazioni come queste, il compilatore è comunque in grado di contare il numero di elementi dell’array e allocare la memoria necessaria. Un elemento di array può essere usato in un programma alla stregua di una variabile scalare perchè ad esso corrisponde una locazione di memoria il cui indirizzo è univocamente associato all’indice (o agli indici) che lo contraddistingue. Per fare riferimento a un elemento di array si usa il nome dell’array seguito da tanti indici quante sono le dimensioni dell’array separati da virgole e racchiusi fra parentesi. Un indice è una costante, una variabile o un’espressione di tipo intero.

Consideriamo il seguente programma MEDIA ARITMETICA, che calcola e stampa la media dei voti riportati da un certo numero di studenti in un corso di laurea il cui regolamento prevede 17 esami.

PROGRAM MEDIA ARITMETICA
∗ Programma che calcola la media dei voti riportati da uno o più
∗ studenti per un numero massimo di esami pari a 17
PARAMETER (NM=17)
INTEGER V(NM)
10 PRINT∗, ’immettere il numero N di esami superati’
PRINT∗, ’Attenzione: N deve essere <=’,NM
READ∗, N
PRINT∗, ’immettere i voti’
READ∗, (V(I), I=1,N)
SMEDIA=0.
DO 100 I=1,N
SMEDIA=SMEDIA+V(I)
100 CONTINUE
SMEDIA=SMEDIA/N
PRINT∗,’media= ’, SMEDIA
PRINT∗,’ancora? (1/0= si/no)’
READ∗,LEGGI
IF(LEGGI.EQ.1) GOTO 10
END

Per ogni studente si legge il numero n ≤ 17 di esami superati e i relativi voti, che vengono memorizzati in un vettore V. L’istruzione READ∗, (V(I), I=1,N) è la traduzione Fortran dell’istruzione “Leggi v1, . . . , vn”, tramite la quale si leggono tutti i voti di uno studente.

Le istruzioni:
DO 100 I=1,N
SMEDIA=SMEDIA+V(I)
100 CONTINUE
sono la traduzione FORTRAN del ciclo Per i = 1, ... , n
Poni media = media + vi

Nelle istruzioni PRINT che precedono la lettura di N abbiamo fatto in modo che il valore (17) della costante NM venga visualizzato sullo schermo prima che l’utente inserisca il valore di N.


Costanti intere, reali, esponenziali, complesse
Le intere non hanno punti (ad esempio 0 oppure 7 o ancora 777 o ancora -5)
Nelle reali invece compare il decimale (ad esempio 0.1 o ancora -0.57) rappresentato da un punto e non dalla virgola. L'esponenziale è evidenziato dalla E (4.E3).
Una costante complessa è data da una coppia di costanti reali separate da una virgola e racchiuse fra parentesi tonde: la prima costante rappresenta la parte reale del numero e la seconda la parte immaginaria. Ad esempio, la costante (–0.2, 2.4E–2) identifica il numero complesso –0.2+0.024i).


Costanti logiche e carattere
Le logiche sono semplicemente .TRUE e .FALSE
Carattere invece: 'immettere il perimetro del triangolo' oppure 'immettere la lunghezza dell'ipotenusa' (insomma ciò che il programma stampa sullo schermo).


Operazioni aritmetiche
A + B
A - B
A * B
A / B
A**B

Abbiamo semplicemente: la somma di A più B, la differenza tra A e B, la moltiplicazione di A e B,
la divisione di A e B e l'elevamento di A alla potenza B. L’ordine con cui vengono scritte definisce il modo di operare nelle operazioni matematiche. Prima il contenuto in parentesi da sinistra a destra.
Esponenziale sempre da sinistra a destra. Ad esempio Y=A**B**C darà lo stesso risultato di Y=A**(B**C). Moltiplicazioni o divisioni da sinistra a destra. Addizioni o sottrazioni da sinistra a destra.


Funzioni matematiche
ABS(A) Valore assoluto di A
ASIN(A) Arcoseno di A
ACOS (A) Arcocoseno di A
ATAN(A) Arcotangente di A
COS(A) Coseno di A
SIN(A) Seno di A
TAN(A) Tangente di A
EXP(A) Esponenziale di A
LOG(A) Logaritmo naturale di A
LOG10(A) Logaritmo naturale di A in base 10
SQRT(A) Radice quadrata di A
MIN(A,B) Ritorna il valore minimo tra A e B
MAX(A,B) Ritorna il valore massimo tra A e B


Operatori logici
A e B sono variabili logiche
A.AND.B vero se sia A sia B sono vere
A.OR.B vero se A è vera oppure lo e' B.
A e B variabili o espressioni numeriche
A.EQ.B vero se A è uguale a B
A.GT.B vero se A è maggiore di B
A.GE.B vero se A è maggiore o uguale a B
A.LT.B vero se A è minore di B
A.LE.B vero se A è minore o uguale a B


Comandi di controllo
STOP Sospende l'esecuzione
CONTINUE Continua l'esecuzione
END Termina il programma
IF(esp) cmd Se l'espressione esp è vera allora il comando cmd viene eseguito
IF(esp) THEN
cmd1
cmd2
....
ENDIF Se l'espressione esp è vera allora i comandi cmd1, cmd2, ... fino al comando ENDIF sono eseguiti.

IF(esp) THEN
cmd1
ELSE
cmd2
ENDIF Se l'espressione esp è vera allora i comandi cmd1 fino a ELSE sono eseguiti, altrimenti sono eseguiti i comandi cmd2 fino a ENDIF.

IF(esp1) THEN
cmd1
ELSEIF (esp2)
cmd2
ENDIF Se esp1 è vera i comandi cmd1 sono eseguiti se invece è vera l'espressione esp2 sono eseguiti i comandi cmd2.

DO INDX=N1,N2,INCR
comandi1
ENDDO Ripete i comandi1 fino a che l'indice INDX non supera il valore N2.
Il primo valore di INDX (intero) è N1 (intero) ad ogni ripetizione del comando questo valore viene incrementato del valore INCR (intero) fino a quando non è maggiore di N2 (intero).
Se INCR non è esplicitato viene utilizzato il valore di default INDX=1.
INCR può anche assumere valori interi negativi.
In questo caso N2 sarà minore di N1 e la ripetizione dei comandi terminerà quando il valore di INDX sarà minore di N2.

GOTO nmr Invia l'esecuzione al comando induviduato dal numero di linea nmr.


Comandi di input -- output
READ(5,1000) A,B Leggi dall'unità 5 i valori delle variabili A e B secondo il formato definito dal comando 1000
READ(5,*) A,B Come sopra. Il formato adesso è libero, fissato dalla dichiarazione delle variabili A e B
READ(5,'(f10.5,1x,f10.5)') A,B Come sopra. In questo caso il formato di lettura è specificato nel secondo argomento del comando READ
WRITE(8,1000) A,B Scrivi sull'unità 8 i valori delle variabili A e B secondo il formato definito dal comando 1000. L'utilizzazione dei formati eè analoga a quella del comando READ.
OPEN (UNIT=8,FILE='fn.dat',STATUS='OLD') Apri l'unità numero 8, il cui nome è fn.dat e il cui status OLD dice che esiste già. All'unità può essere assegnato qualsiasi numero intero.
Il nome del file può essere assegnato anche con una variabile stringa. Le possibili opzioni di STATUS sono: OLD, il file già esiste, NEW, il file viene creato durante l'esecuzione, UNKOWN, se il file non esiste viene creato.


Formati di lettura e scrittura
FORMAT E' il comando che indica il formato di scrittura e/o lettura.
I4 Per numeri interi. Il 5 indica che sono allocati 4 spazi per la lettura/scrittura, uno di questi è utilizzato per il segno.
F10.4 Per numeri reali. Sono allocati dieci spazi di cui 4 per i decimali. Bisogna considerare che in questi 10 spazi sono inclusi il punto ed il segno.
E12.5 Per numeri reali espressi in notazione scientifica. Sono allocati 12 spazi di cui 5 per i decimali. Nei 12 spazi sono inclusi il punto, il segno, il segno dell'esponente, la E dell'esponente e due cifre dell'esponente. A10 Per caratteri stringa. Sono allocati 10 caratteri.


Sottoprogrammi
FUNCTION name (A,B) La FUNCTION restituisce al programma principale un solo valore numerico che è associato al nome della function (nell'esempio name).
Nella FUNCTION deve essere presente il comando: name= variabile
Il comando RETURN riporta l'esecuzione al programma principale.
A e B sono variabili definite nel programma principale che vengono passate alla FUNCTION.
SUBROUTINE name (A,B) La SUBROUTINE restituisce al programma principale varie quantità. Le quantità calcolate nella SUBROUTINE che devono essere restituite al programma principale vengono passate nell'argomento della SUBROUTINE, insieme alle variabili di ingresso.
COMMON /name/ A,B E' un modo per mettere in comune variabili (A e B nell'esempio) tra vari sottoprogrammi e programma principale. Ogni volta che il valore numerico di A e B verrà modificato, questa modifica sarà registrata in tutti i sottoprogrammi in cui il COMMON/name/ è presente.

1 commento: