Fortran 90[/95] Info Linguaggi di programmazione Linguaggi

Info
Fortran 90[/95]
Mauro Bianco
Usare il compilatore con windows
• Aprire una finestra DOS
– Si dovrebbe trovare sul menu si avvio
– Aprire il menu, selezionare esegui/run e digitare
“cmd” o “command”
•
•
•
•
Posizionarsi sulla cartella di lavoro
Lanciare il compilatore come in unix
cp=copy, mv=ren, rm=del
Attenzione alle estensioni dei file! Potrebbe non
essere così facile cambiarle!
Linguaggi Imperativi
• Stesso approccio del linguaggio macchina
• Sequenza di istruzioni
• Istruzioni di vario tipo
– Aritmetico-logiche
– Confronti
–…
– Concetto di variabile
• Utile alla realizzazione di algoritmi come li
abbiamo definiti (sequenza di passi)
• Il compilatore gfortran per windows funziona?
• G95 dovrebbe funzionare abbastanza bene,
quindi potete utilizzare quello
• Consiglio, comunque, se non avete gfortran di
provare i programmi che fate in laboratorio con
gfortran
Linguaggi di programmazione
• Linguaggio Macchina
• Linguaggio Assembly
• Linguaggi di Alto Livello
– Imperativi (C, Pascal, Fortran,…)
– Funzionali (Lisp)
– Logici (Prolog)
– Orientati agli Oggetti (Java, C++,…)
Linguaggi Funzionali e Logici
• Funzionali
– Basati solo sul concetto di funzione
– Non esistono le variabili ma solo funzioni che
possono essere argomenti di altre funzioni
• Logici
– Stile dichiarativo: il programmatore specifica
quello che sa del problema (fatti) (A IF B C)
– Si interroga il sistema che deduce la soluzione
del problema dai fatti noti
1
Object Oriented Programming
• Derivati dai linguaggi imperativi
• I dati sono associati a delle procedure
(sequenze di istruzioni)
• Possibilità di creare delle entità autonome
• Possibilità di creare entità più specifiche da
entità più generali
Set di Caratteri
• Caratteri legali:
– Lettere: a-z e A-Z (Fortran non fa differenza tra
maiuscole e minuscole)
– Cifre: 0-9
– Sottolineatura: _
– Operatori matematici: + - * / **
– Speciali: ( ) . = , $ : ! “ % & ; < > ?
– Spazio vuoto
PROGRAM my_first_program
! Purpose:
!
To illustrate some of the basic features of a
!
Fortran program.
!
! Declare the variables used in this program.
INTEGER :: i, j, k
! All variables are
! integers
! Get the variables to multiply together.
WRITE (*,*) 'Enter the numbers to multiply: '
READ (*,*) i, j
! Multiply the numbers together
k = i * j
! Write out the result.
WRITE (*,*) 'Result = ', k
Fortran: Dove si usa
• Calcolo scientifico e tecnico
– Calcolo numerico
• Calcolo ad alte prestazioni (esistono
compilatori molto sofisticati)
• Calcolo parallelo (Es. HPF: High
Performance Fortran)
Tipi di Istruzioni
• Eseguibili
– Operazioni matematiche e logiche
– Confronti
– Cicli
– I/O
• Non eseguibili
– Definizioni di tipi e di variabili
– Definizioni di routine e funzioni
– Inizio e fine dei programmi
Struttura di un programma
• Sezione dichiarativa: Nome del programma (o
della routine, o della funzione), il tipo e il nome
delle variabili utilizzate
• Sezione esecutiva: Istruzioni che descrivono le
azioni che il programma deve compiere
• Sezione conclusiva: Dichiarazione di fine
programma (o routine, o funzione)
! Finish up.
STOP
END PROGRAM
2
Nomi di programmi e di variabili
Variabili
• Composti da 31caratteri
• La prima lettera deve essere una lettera
dell’alfabeto
• Le altre lettere possono essere lettere
dell’alfabeto, cifre o “_”
• [a-zA-Z][a-zA-Z0-9_]{0,30}
• “VaRiaBLe” è uguale a “vAriablE”
• Lo stesso vale per tutti i nomi e le parole chiave
• Identificatori che possono assumere valori di un
certo tipo
• Una variabile è il nome dell’indirizzo di
memoria che contiene il dato
• integer :: num
• num è una variabile di tipo intero
• Esistono cinque tipi di dati di base (impliciti) in
Fortran90
– Integer, real, complex, logical, character
Inizializzazione delle variabili
program prova
Integer :: i
WRITE (*,*) i
end program prova
• Cosa stampa la write? Alcuni compilatori
inizializzano a zero, altri danno un messaggio di
errore al run-time, altri ancora restituiscono un
valore “casuale”
– Mantissa
– Esponente
d
m ×10
– mEd, med
Valide
0.
-10.4
13.E-4
.999E5
-045.9
• INTEGER :: A=100 !
assegna ad A il valore 100
• “100” è una costante
• [+-]{0,1}[0-9]+
• Segno + o – opzionale
• Sequenza di cifre da 0 a 9
• La lunghezza dipende dal
tipo (numero di bit)
Valide Non Valide
0
1.000,5
+12
1,000.5
023
--12
999
-45
Costanti caratteri
Costanti reali
• Deve contentere il
punto decimale
• Notazione decimale
• Notazione scientifica
Costanti intere
Non Valide
1.000,5
1,000.5
3E4
23.4E3.4
• Tutti i caratteri
codificabili sono
possibili!
• I caratteri sono
contenuti in virgolette
singole o doppie
• Per includere le
virgolette ripetere il
simbolo
Valide
Non Valide
“Ciao”
Ciao
‘Ciao’
“Ciao’
‘l’’ape’
‘l’ape’
“l’ape”
‘l’ape
“45E3.{”
‘’ciao’
3
Costanti logiche
• Vero: .true.
• Falso: .false.
Dichiarazioni di tipo
Valide
Non Valide
.true.
true
.false.
.false
.TRUE.
false.
.FAlsE.
V
.True.
F
Variabili implicite e esplicite
• Se non dichiarate nella sezione dichiarativa le
variabili che iniziano con I, J, K, L, M, N sono
INTEGER, le altre sono REAL
• ERROR PRONE
• Evitare i problemi con IMPLICIT NONE
• Forza a usare le istruzioni di dichiarazione di
tipo
• Fornisce errori in compilazione se ci sono
variabili non dichiarate
PROGRAM my_first_program
! Purpose:
!
To illustrate some of the basic features of a
!
Fortran program.
!
IMPLICIT NONE
! Declare the variables used in this program.
INTEGER :: i, j
! All variables are
! integers
! Get the variables to multiply together.
WRITE (*,*) 'Enter the numbers to multiply: '
READ (*,*) i, j
! Multiply the numbers together
k = i * j
! Write out the result.
WRITE (*,*) 'Result = ', k
•
•
•
•
•
TIPO :: nome1, nome2=val, nome3
INTEGER :: age, score=50
REAL :: temp=37., height
CHARACTER(15) :: nome, nick=“nick”
I “::” sono facoltativi in queste semplici
dichiarazioni ma obbligatori in casi più
complessi! Usateli sempre per non sbagliare
PROGRAM my_first_program
! Purpose:
!
To illustrate some of the basic features of a
!
Fortran program.
!
! Declare the variables used in this program.
INTEGER :: i, j
! All variables are
! integers
! Get the variables to multiply together.
WRITE (*,*) 'Enter the numbers to multiply: '
READ (*,*) i, j
! Multiply the numbers together
k = i * j
! Write out the result.
WRITE (*,*) 'Result = ', k
! Finish up.
STOP
END PROGRAM
Nomi alle costanti
• REAL, PARAMETER :: pi=3.14159
• Se nel programma si cerca di modificare il
valore di “pi” si ottiene un errore di
compilazione
• Questo evita errori nel caso in cui il valore
3.14159 debba essere usato più volte!
Se si chiamasse
“b”?
! Finish up.
STOP
END PROGRAM
4
Istruzione di assegnazione
• Il simbolo “=“ non è il simbolo di
ugualianza ma di assegnazione
• A=100 assegna ad A il valore 100
• I=I+1 aggiunge 1 al valore di I e assegna il
risultato alla variabile I
• A sinistra di = il nome di una variabile
• A destra di = qualsiasi espressione valida
Le istruzioni
• Si può andare a capo con una istruzione mettendo il
carattere “&” alla fine della riga
• I caratteri che seguono, nella riga, il “!” vengono
ignorati dal compilatore (COMMENTI!)
• output=input1+input2 ! Somma i1 e i2
• output=input1 & ! meta’ istruzione
+input2
• 898 output=input1+input2
• L’etichetta non induce un ordinamento delle istruzioni,
serve solo a identificare l’istruzione!
Operazioni tra reali
• Le operazioni tra reali hanno come risultato
numeri reali
• Attenzione: numero reale non vuol dire
appartenente a un continuo. In generale il
risultato di una operazione è una
approssimazione
• 3./4.=0.75, 4./4.=1.
• 1.+1e-16=1.
Espressioni valide
Valide
Non Valide
a+b*c
a(b+c)
-a
a*-b (gfortran la accetta)
a*(b+c)
a**-4 (gfortran la accetta)
2**6
a*(b-f
a+3.45**c
Operazioni tra interi
• Le operazioni tra interi hanno come
risultato numeri interi
• 3/4=0, 4/4=1, 19/5=3, 20/5=4, 21/5=4
• L’operazione eseguita sul risultato è un
troncamento
Ordine di precedenza
• Regole simili all’algebra ordinara
1. Operazioni nelle parentesi da quelle interne a quelle
esterna
2. Potenze da sx a dx
3. Prodotti e divisioni da sx a dx
4. Somme e sottrazioni da sx a dx
• 1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e8+1.e-8+1.e-8+1.e-8+1.
• 1.+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e8+1.e-8+1.e-8+1.e-8
5
Operazioni miste
Operazioni miste
• In operazioni miste tra reali e interi i numeri
interi vengono convertiti in reali
• Bisogna però fare molta attenzione! La
conversione avviene in ogni “sottocalcolo”
• Elevamento a potenza richiede che
l’esponente sia intero!
• Altre relazioni vanno applicate per calcolare
l’elevamento a potenza con esponenti reali
• 1.+1/4=1.
• 1.+1./4=1.25
– xy = eylnx
• Usare conversioni esplicite: REAL(I),
INT(A), NINT(A)
Operazioni logiche
Operazioni logiche
• Variabili logiche del tutto analoghe alle
variabili degli altri tipi
• LOGICAL :: test1, test2
• test1=.true.
Non confondere “=“
• test2=(a>b)
con “==“!!
• test2=test1 .or. (c<t)
Il compilatore
dovrebbe avvertire,
• test1=(a==b)
ma…
• .and., .or., .eqv., .neqv., .not.
• (.neqv. è chiamato xor nelle dispense)
• Valutati dopo gli operatori aritmetici e
relazionali (>, <, >=, <=, ==, /=) da sx a dx
• “WRITE (*,*) test1” produce “T” o “F” se
test1 è .true. o .false. (risp.)
• WRITE (*,*) a==b
Input/Output in Formato Libero
Input/Output in Formato Libero
• Input: READ (*,*) <lista di input>
• <lista di input> lista di variabili separate da
virgole
• (*,*) dice di leggere da standard input in
formato libero
• Quello che viene letto dipende dal tipo delle
variabili nella lista
•
•
•
•
•
INTEGER :: a
REAL :: b
CHARACTER(10) :: c
READ (*,*) a,b,c
Legge a di tipo intero, b di tipo reale e c di tipo
stringa di caratteri di lunghezza 10 (troncandola
se più lunga)
6
Input/Output in Formato Libero
• WRITE (*,*) <lista di output>
• <lista di output> lista di variabili e costanti
separate da virgole
• (*,*) dice di leggere su standard output in
formato libero
• Quello che viene scritto dipende dal tipo
delle variabili e delle costanti nella lista
Errori
• Errori di compilazione: errori sintattici:
– Errori di battitura
– Il compilatore cerca di fornire messaggi amichevoli,
indicando riga e colonna in cui l’errore si verifica,
ma a volte possono essere fuorvianti
• Errori al run-time: il programma si interrompe
quando viene eseguito con qualche messaggio
di errore
– Conoscere il run-time system (l’ambiente di
esecuzione) aiuta a eliminare questi errori
Debug
• Debug: ricerca e correzione degli errori (bug)
• Errori in esecuzione e errori logici possono
essere trovati inserendo delle istruzioni di
stampa dei valori delle variabili utilizzate dal
programma
• Usare il debugger! Strumento molto flessibile
ma anche di non immediata comprensione per i
neofiti
Input/Output in Formato Libero
•
•
•
•
INTEGER :: a
REAL :: b
CHARACTER(10) :: c
WRITE (*,*) a, ”Stringa”, b, 34, c
Errori
• Errori Logici: il programma esegue senza
interrompersi ma i risultati sono scorretti
– Errori nella progettazione
– Errori di battitura
• Operatori errati
• Variabili sbagliate o non inizializzate
• IMPLICIT NONE aiuta a limitare i danni
• Più gli errori appaiono tardi nel processo, più
sono difficili da individuare!
Istruzione IF
…
IF (espr. logica) THEN
istr. 1
istr 2.
…
END IF
…
7
Istruzione IF
…
IF (espr. logica) THEN
istr. 1
…
ELSE
istr. A
…
END IF
…
Esempio
IF (a>3) THEN
a=a-1
b=b+1
ELSE IF (A<3) THEN
a=a+1
b=b+2
ELSE
b=b+3
END IF
Istruzione IF
…
[<nome>:] IF (espr. logica) THEN
istr. 1
…
ELSE [<nome>]
istr. A
…
END IF [<nome>]
…
Istruzione IF
…
IF (espr. logica1) THEN
istr. 1
…
ELSE IF (espr. logica 2) THEN
istr. A1
…
ELSE
istr. B1
…
END IF
…
ELSE e ELSE IF vanno
su righe separate e non
etichettate
Istruzione IF
…
[<nome>:] IF (espr. logica) THEN
istr. 1
istr 2.
…
END IF [<nome>]
…
Istruzione IF
…
[<nome>:] IF (espr. logica1) THEN
istr. 1
…
ELSE IF (espr. logica 2) THEN [<nome>]
istr. A1
…
ELSE [<nome>]
istr. B1
…
END IF [<nome>]
…
8
Esempio
IF (a>3) THEN
a=a-1
IF (b==5) THEN
b=6
ELSE
b=5
END IF
ELSE IF (a<3) THEN
a=a+1
END IF
Ancora IF
•
•
•
•
•
IF (espressione) istruzione
Non c’è THEN
Una sola istruzione dopo l’espressione
IF (a>max) max=a
Equivale a:
IF (a>max) THEN
max=a
END IF
SELECT CASE
• case_expr è una espressione il cui valore viene
confrontato con i selettori
• Un selettore specifica un lista di range, se case_expr è
nel range di un selettore, il blocco di istruzioni
corrispondente viene eseguito
• Un range può essere specificato come
–
–
–
–
valore
esegue il blocco se case_expr==valore
valore:
esegue il blocco se case_expr>=valore
:valore
esegue il blocco se case_expr<=valore
val1:val2 esegue il blocco se val1<=case_expr<=val2
Esempio
esterno: IF (a>3) THEN
a=a-1
interno: IF (b==5) THEN
b=6
ELSE interno
b=5
END IF interno
ELSE IF (a<3) THEN esterno
a=a+1
END IF esterno
SELECT CASE
[<nome>:] SELECT CASE (case_expr)
CASE (selettore1) [<nome>]
istr…
…
CASE (selettore 2) [<nome>]
istr…
…
CASE DEFAULT [<nome>]
istr…
…
END SELECT [<nome>]
SELECT CASE
INTEGER :: valore
SELECT CASE (valore)
CASE (1,2,3,5,7,11,13)
WRITE (*,*) “Numero primo”
CASE (4,6,8:10,12,14:15)
WRITE (*,*) “Non primo”
CASE (16:)
WRITE (*,*) “Troppo grande”
CASE DEFAULT
WRITE (*,*) “ERRORE!”
END SELECT
9
SELECT CASE
Progettazione: metodo TOP-DOWN
• Permette una maggiore chiarezza rispetto a
usare IF-THEN-ELSE IF…
• Un certo valore non può apparire in due
istruzioni CASE
• Le espressioni devono essere intere, logiche o
caratteri singoli
• Il nome può essere usato se si usano costrutti
innestati o se i blocchi di istruzioni sono troppo
lunghi
• Dalla specifica del problema alla progettazione
dell’algoritmo
• Divisione del problema in sottoproblemi
• Divisione dei sottoproblemi in sottoproblemi
fino a che questi non siano ritenuti abbastanza
semplici da essere risolti direttamente
• Non esagerare nella frammentazione, il
programma risultante potrebbe risultare
illeggibile
• Sfruttare la modularità
Progettazione: metodo TOP-DOWN
Progettazione: metodo TOP-DOWN
• I sottoproblemi devono essere il più possibile
indipendenti gli uni dagli altri
• Le interfacce (I/O) tra i sottoproblemi devono
essere definite in modo chiaro e robusto
• Una volta definito il sottoproblema e la sua
interfaccia si passa alla sua implementazione
• Ogni sottoprogramma va testato
indipendentemente dagli altri
• Quando i sottoprogrammi sono stati testati si
passa alla loro integrazione nel prodotto finito
• Il processo può avvenire per passi successivi,
ogni passo va però testato con un test di
integrazione
• Quando tutto il programma è stato prodotto
viene eseguito il test di integrazione del
programma
La fase di specifica
• Specificare il problema da risolvere è una
componente molto delicata e, tipicamente, poco
formale
• Necessario specificare l’ingresso e l’uscita del
programma
• Sono spesso necessarie parecchie iterazioni per
stabilire in modo rigoroso quale sia il problema
da risolvere
• Spesso la fase di definizione del problema
prosegue anche in fase di sviluppo e di test
Waterfall model
Analisi dei requisiti
Scomposizione in sottoproblemi
Sviluppo delle componenti
Test delle componenti
Integrazione
Test di integrazione
Produzione e assistenza
10
Pseudocodice
• Per specificare gli algoritmi in fase di progetto
non si utilizza il linguaggio di programmazione
• Alcuni costrutti linguistici ne sono derivati,
come IF, DO, WHILE, etc.
• L’assegnazione viene spesso indicata con
per l’ambiguità tra l’uguaglianza e
l’assegnazione (A 100 al posto di A=100)
• L’importante è essere rigorosi ed evitare
ambiguità!
Diagrammi di flusso
Inizio
A
B
Leggi input
Funzione 1
Funzione 2
Esegui istruzione
Output
Ouput
.false.
Se risultato > 0
B
.true.
Fine
A
CICLI
• Sequenza di istruzioni da ripetere fino a che una
determinata condizione si verifica
• I cicli possono essere determinati (si conosce
esattamente il numero di iterazioni) o
indeterminati (il numero è ignoto a priori – ma
finito)
• I primi vengono detti cicli iterativi i secondi
cicli while
DO
DO
Istr.
…
IF (condizione) EXIT
Istr.
…
END DO
L’istruzione EXIT può
essere usata come qualsiasi
altra istruzione
CICLI
Può essere
vuoto
Istruzione
Istruzione
…
Deve condurre a
terminazione il
ciclo!
.true.
Condizione
Può essere
vuoto
.false.
Istruzione
Istruzione
…
Avere un solo punto di ingresso e un
solo punto di uscita sarebbe auspicabile,
ma spesso questa regola non si applica
per non complicare ancora di più il
programma
DO
Istr.
…
DO
Istr.
…
IF (condizione) EXIT
Istr.
…
END DO
Istr.
…
END DO
11
esterno: DO
Istr.
…
interno: DO
Istr.
…
IF (condizione) EXIT esterno
Istr.
…
END DO interno
Istr.
…
END DO esterno
DO iterativo
[<nome>:] DO i=begin, end, step
Istr.
Corpo del ciclo (possono esserci EXIT)
…
END DO [<nome>]
• Eseguito (end-begin+step)/step volte
• Alla prima iterazione i prende il valore begin
• Al termine di ogni itrazione i i+step
• Il ciclo termina quando i*step<=end*step
}
PROGRAM primalita ! Testa se un numero e` primo
INTEGER :: n, i ! n e` il numero, i e` l’indice di ciclo
LOGICAL :: primo ! Vero se n e` primo
WRITE (*,*) “Inserire numero”
READ (*,*) n
primo=.TRUE.
DO i=2,n/2 ! Testa la divisibilita` di n con i
if ((n/i)*i == n) primo == .FALSE.
END DO
IF (primo) THEN
WRITE (*,*) n, “e` primo”
ELSE
WRITE (*,*) n, “non e` primo”
END IF
END PROGRAM primalita
DO WHILE
[<nome>:] DO WHILE (condizione) ! Cicla se vera
Istr.
…
[EXIT [<nome>]] ! Possono esserci degli EXIT
Istr.
…
END DO [<nome>]
DO iterativo
• Il valore di uscita della variabile indice è il primo
valore che non soddisfa alla condizione
i*step<=end*step
• I valori di inizio, fine e incremento vengono fissati
all’inizio del ciclo
DO i=begin, end, step
end=2*end ! Non ha effetto sul numero di iterazioni
i=i+3 ! Segnala un errore in compilazione!!!
…
END DO
Algoritmo di Euclide (GCD)
• b|a => b=GCD(a,b)
• a>b e se m=GCD(a,b) => m=GCD(a-b,b)
– m|(a-b) per ipotesi
– Se esistesse M>m tale che M=GCD(a-b,b), allora
M|b e M|(a-b) => M|a => M>m=GCD(a,b) ->
Contraddizione!
– Sottraendo numeri piccoli da numeri grandi
terminiamo l’algoritmo quando troviamo due numeri
uguali
12
program euclide
integer :: a,b,MCD
write (*,*) "Inserire i due numeri"
read (*,*) a,b
write (*,*) "MCD tra ", a, "e", b, "e`: "
do while ((a-b)/=0)
if (a>b) then
if (a<=0 .or. b<=0) then
a=a-b
write (*,*) "I numeri devono essere positivi"
else
stop
b=b-a
end if
end if
end do
write (*,*) a
stop
end program euclide
DO
Istr.
…
DO
Istr.
…
IF (condizione) CYCLE
Istr.
…
END DO
Istr.
…
END DO
Funzioni intrinseche
• Funzioni fornite dal linguaggio
• Calcolano un valore (risultato) a partire dai
valori dei suoi argomenti
• Esempio: y=sin(x), dove x e y sono reali, y
conterrà il seno di x.
• Alcune funzioni restituiscono un risultato dello
stesso tipo dei dati degli argomenti
– Esistono funzioni specializzate per tipi specifici
CYCLE e EXIT
• EXIT [<nome>] può essere usata in
qualsiasi tipo di ciclo
• CYCLE [<nome>] fa partire la prossima
iterazione del ciclo
• Può essere usato in qualsiasi tipo di ciclo
• Nei cicli iterativi CYCLE l’indice del ciclo
viene incrementato
Funzioni intrinseche
• Fortran fornisce un grande numero di
funzioni implicite (nel senso che non
devono essere implementate dal
programmatore, sono già disponibili)
• Esempi: SIN, COS, LOG, LOG10, ABS,…
• Esempio: ABS accetta ingressi reali o interi.
Per esplicitare il tipo si può usare IABS per
gli interi (pag. 539 del libro)
Funzioni intrinseche
INTEGER :: i
REAL :: a ! Singola precisione REAL(4)
REAL(8) :: b ! Doppia precisione
COMPLEX :: c ! Complesso in singola precisione
COMPLEX(8) :: d ! Complesso in doppia precisione
ABS(i) è intero
Alt. IABS(i)
ABS(a) è reale s.p.
Alt. ABS(a)
ABS(b) è reale d.p.
Alt. DABS(b)
ABS(c) è reale s.p.
Alt. CABS(c)
ABS(d) è reale d.p.
Alt. ZABS(d)
13
Esempio
• Dati giorno, mese e anno determinare il giorno
dell’anno corrispondente (da 1 a 366)
• Input: 3 numeri interi (non prevediamo messaggi di
errore nel caso di dati sbagliati)
• Output: un numero intero compreso tra 1 e 366
• Progetto: sottoproblemi
Esempio: input
• giorno (intero)
• mese (intero)
• anno (intero)
– Capire se un anno è bisestile o no (sottoproblema 1)
– Sommare i giorni relativi ai mesi precedenti quelli della data
in ingresso (sottoproblema 2)
• Dato un mese, quanti giorni ha? (sottoproblema 3)
– Sommare i giorni del mese corrente (sottoproblema 4)
Esempio: sottoproblema 1
• Un anno è bisestile se
– È divisibile per 400
– Altrimenti deve essere divisibile per 4 ma non per
100
• Altrimenti non è bisestile
Esempio: sottoproblema 3
• Dato il mese quanti giorni ha?
• I mesi hanno durate variabili
– 30 giorni ha novembre (11) con aprile (4),
giugno (6) e settembre (9)
– Febbraio ne ha 28 o 28+1 nel caso di anno
bisestile
– I mesi 1, 3, 5, 7, 8, 10, 12 ne hanno 31
Esempio: sottoproblema 1
IF (MOD(anno, 400)==0) THEN
bisestile = .true.
ELSE IF ((MOD(anno, 4)==0) .and. &
.not.(MOD(anno, 100)==0)) THEN
bisestile = .true.
ELSE
bisestile = .false.
END IF
Esempio: sottoproblema 3
CASE SELECT (mese_corrente)
CASE (4,6,9,11)
giorni_mese=30
CASE (2)
giorni_mese=28
if (bisestile) giorni_mese=giorni_mese+1
CASE (1,3,5,7,8,10,12)
giorni_mese=31
END SELECT
14
Esempio: sottoproblema 2
giorni=0
DO mese_corrente=1,mese-1
Risolvi sottoproblema 3
giorni=giorni+giorni_mese
END DO
Esempio: sezione dichiarativa
• INTEGER :: giorno, mese, anno ! Input
• INTEGER :: giorni, giorni_mese ! Var. ausiliarie
• LOGICAL :: bisestile
Altre versioni?
• Nel libro di testo si usa leap_day che vale zero o
uno e va sommato ai giorni del mese di febbraio
• Non si usa la variabile giorni ma direttamente
giorno che viene incrementato del valore giusto
• Di fatto due programmi calcolano la stessa
funzione, e sono quindi del tutto equivalenti
• Di norma si dovrebbe scegliere la realizzazione
in base alle esigenze: in questo corso si
preferisce la chiarezza del programma stesso!
Esempio: sottoproblema 4
giorni=giorni+giorno
Sottoproblema 4 revised
bisestile = (MOD(anno,400)==0) .or. &
((MOD(anno, 4)==0) .and. &
.not.(MOD(anno, 100)==0))
• Un programma deve raggiungere un
compromesso tra chiarezza e
sinteticità/efficienza
• Questa formula è chiara o è meglio
utilizzare gli IF?
Caratteri
CHARACTER :: c
c=‘a’ ! Apici singoli e doppi sono intercambiabili
CHARACTER(len=3) :: c
c=‘a’ ! Completa c con degli spazi ‘a ‘
CHARACTER(3) :: c
c=‘slide’ ! Prende solo le prime cifre c=‘sli’
15
Caratteri: sottostringhe
CHARACTER(9) :: a,b=‘certifico’
a=‘sincopato’
write (*,*) a(2:4) ! Stampa ‘inc’
a(5:8)=‘erat’
write (*,*) a ! Stampa ‘sincerato’
b(3:5)=a(2:7)
write (*,*) b ! Stampa ‘ceincfico’
write (*,*) a(3:6) // b(5:7) ! Stampa ‘ncercfi’
Caratteri: confronti
• ‘a’==‘a’
• ‘a’/=‘A’, ‘a’>’A’
• ‘Magno’ == ‘Magno’, ‘Magno’ < ‘magno’,
‘Magno’ > ’Magna’
• ‘Magnolia’ > ’Magno’
• ‘Carlo Magno’ < ‘CarloMagno’
Caratteri: confronti
• I confronti vengono fatti in base all’ordinamento
dei simboli nel set di caratteri del calcolatore
• In genere si usa il codice ASCII: a ogni simbolo
è associato un numero tra 0 e 255
• Le stringhe vengono confrontate da sinistra a
destra carattere per carattere, il primo carattere
diverso detta l’ordinamento tra le due stringhe
• Quando si raggiunge la fine di una stringa,
quella più lunga viene dopo quella corta
nell’ordinamento
Caratteri: funzioni
• ACHAR(i) il carattere corrispondente a i
• ICHAR(c) l’intero corrispondente al carattere c
• LEN(str) la lunghezza (numero caratteri) della
stringa str
• LEN_TRIM(str) lunghezza di str senza gli spazi
finali (a destra)
• TRIM(str) la stringa str senza gli spazi finali
• ADJUSTL, ADJUSTR, etc.
16