Il linguaggio Fortran 90:
2. Istruzioni di Controllo
1
Strutture di Controllo
• Programmi visti in precedenza permettono di eseguire le
istruzioni solo nella sequenza indicata.
• La risoluzione di molti problemi richiede la scrittura di
programmi in cui le azioni che si svolgono dipendono
dall’input del problema.
• Strutture di controllo permettono di alterare la sequenza di
esecuzione delle istruzione del programma al verificarsi di
determinate condizioni.
• Due tipi fondamentali di istruzioni di controllo:
Istruzioni Condizionali
Cicli
2
Istruzioni Condizionali
nome: IF (condizione) THEN
istruzione 1
istruzione 2
END IF nome
________________________________
nome: IF (condizione) THEN
istruzione 1
istruzione 2
ELSE
istruzione 1
istruzione 2
END IF nome
3
Stampa del maggiore tra due interi
!File: max.for
!Scopo: primo esempio di istruzione condizionale(IF-THEN-ELSE)
PROGRAM max
! Questo programma legge due numeri interi e stampa il maggiore
IMPLICIT NONE
INTEGER :: primo, secondo, maggiore
WRITE (*,*) 'Inserisci due numeri interi, poi schiaccia il tasto RETURN'
READ (*,*) primo, secondo
IF (primo > secondo) THEN
maggiore = primo
ELSE
maggiore = secondo
END IF
WRITE (*,*) 'Il maggiore dei due valori inseriti e'': ', maggiore
STOP
END PROGRAM max
4
Istruzioni condizionali nidificate.
• Le istruzioni condizionali possono essere a loro volta
nidificate.
• Istruzione ELSE IF permette di realizzare IF annidati.
nome: IF (condizione1) THEN
istruzione 1
istruzione 2
ELSE IF (condizione2) THEN
istruzione 1
istruzione 2
ELSE
istruzione 1
istruzione 2
END IF nome
5
Classificazione dei Triangoli 1
! File: triang1.for
! Scopo: applicazione degli IF annidati
PROGRAM triangolo1
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
REAL :: primo, secondo, terzo
! le lunghezze dei tre lati
! *** SEZIONE ESECUTIVA *** !
WRITE (*,*) 'Inserisci le lunghezze dei tre lati del triangolo: '
READ (*,*) primo,secondo,terzo
6
Classificazione dei Triangoli 1 (cont.)
if1: IF (primo == secondo) THEN
if2: IF (secondo == terzo) THEN
WRITE (*,*) 'Equilatero'
! I tre lati sono sono uguali fra loro
ELSE
WRITE (*,*) 'Isoscele'
! 1 coppia di lati uguali fra loro
END IF if2
ELSE
if3: IF (secondo == terzo) THEN
! primo <> secondo
WRITE (*,*) 'Isoscele'
! 1 coppia di lati uguali fra loro
ELSE IF (primo == terzo) THEN
! (primo <> secondo) e (secondo <> terzo)
WRITE (*,*) 'Isoscele'
! 1 coppia di lati uguali fra loro
ELSE
WRITE (*,*) 'Scaleno'
! 0 coppie di lati uguali fra loro
END IF if3
END IF if1
STOP
END PROGRAM triangolo1
7
Classificazione dei Triangoli 2
• Il programma può essere semplificato scegliendo un
diverso algoritmo di soluzione
• If logico: IF (condizione) istruzione
! File: triang2.for
PROGRAM triangolo2
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
REAL :: primo, secondo, terzo
INTEGER :: uguali
! il numero di coppie di lati uguali fra loro
8
Classificazione dei Triangoli 2
! *** SEZIONE ESECUTIVA *** !
WRITE (*,*) 'Inserisci le lunghezze dei tre lati del triangolo: '
READ (*,*) primo,secondo,terzo
uguali = 0
IF (primo == secondo) uguali = uguali + 1
IF (secondo == terzo) uguali = uguali + 1
IF (primo == terzo) uguali = uguali + 1
IF (uguali == 0) THEN
WRITE (*,*) 'Scaleno'
ELSE IF (uguali == 1) THEN
WRITE (*,*) 'Isoscele'
ELSE
WRITE (*,*) 'Equilatero'
END IF
STOP
END PROGRAM triangolo2
9
Espressioni Logiche
• Le condizioni sono espressioni logiche, possono assumere
due valori di verità.
• Costanti logiche: .TRUE. o .FALSE.
• Variabili logiche:
LOGICAL :: variabile_logica
• Operatori relazionali
==, /=, >, >=, <, <=
• Es: (7 + 3) /= 6 .TRUE.
10
Operatori Logici
•
•
•
•
•
Es:
x .AND. y:
x .OR. y:
x .EQV. y:
x .NEQV. y:
.NOT. y:
.TRUE. sse x e y sono .TRUE. (altrimenti .FALSE.)
.TRUE. sse x o y sono .TRUE.
.TRUE. sse x = y
.TRUE. sse x /= y
.TRUE. sse y = .FALSE.
LOGICAL :: x, y, z
x = .TRUE.
y = .FALSE.
z = (x .OR. y) .AND. (x .NEQV. y) .AND. (x /= y) = .TRUE.
11
Regole di precedenza tra operatori logici
1.
2.
3.
4.
5.
6.
Operatori aritmetici
Operatori relazionali da sx a dx
Operatori .NOT. da sx a dx
Operatori .AND. da sx a dx
Operatori .OR. da sx a dx
Operatori .EQV. e . NEQV. da sx a dx
12
Classificazione di triangoli 3
! File: triang3.for
PROGRAM triangolo3
IMPLICIT NONE
REAL :: primo, secondo, terzo
! le lunghezze dei tre lati
WRITE (*,*) 'Inserisci le lunghezze dei tre lati del triangolo: '
READ (*,*) primo,secondo,terzo
IF (primo == secondo .AND. secondo == terzo) THEN
WRITE (*,*) 'Equilatero'
ELSE IF (primo == secondo .OR. secondo == terzo .OR. primo == terzo) THEN
WRITE (*,*) 'Isoscele'
ELSE
WRITE (*,*) 'Scaleno'
END IF
STOP
END PROGRAM triangolo3
13
Calcolo delle radici di un’equazione
di secondo grado
!File: radici.for
PROGRAM radici
!Scopo: Questo programma calcola le radici di un’equazione
! a*x**2+ b*x + c = 0
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
REAL :: a, b, c
REAL :: discriminante, parte_immag, parte_reale
REAL :: x1, x2
! Soluzioni dell’equazione
! *** SEZIONE ESECUTIVA *** !
WRITE (*,*) 'Inserire i tre coeefficienti A, B e C: '
READ (*,*) a, b, c
!Calcola il discriminante
discriminante = b**2 - 4 * a * c
14
Calcolo delle radici di un’equazione
di secondo grado (cont)
! Calcola le radici in funzione del discriminante
IF (discriminante >0) THEN
! due radici reali
x1 = (-b + sqrt(discriminante)) / (2.*a)
x2 = (-b - sqrt(discriminante)) / (2.*a)
WRITE (*,*) 'Due radici reali: ', x1, x2
ELSE IF (discriminante == 0.) THEN
! Radici reali e coincindenti
x1 = ( -b ) / (2. * a)
WRITE (*,*) 'due radici reali e coincidenti: ', x1
ELSE
! Radici complesse
parte_reale = ( -b ) / (2. * a)
parte_immag = sqrt(abs(discriminante)) / (2.*a)
WRITE (*,*) 'due radici immaginarie:', parte_reale, '+/- i', parte_immag
END IF
STOP
END PROGRAM radici
15
L’istruzione Case
nome: SELECT CASE (espressione)
CASE (sel 1)! Se espressione nel
! range di sel 1
istruzione 1
CASE (sel 2) ! Se espressione nel
! range di sel 2
istruzione 2
..
..
CASE DEFAULT ! In tutti gli altri
casi
istruzione
END SELECT nome
16
Calcolo della data del giorno successivo
!File: datasuc1.for
!Scopo: esempio di uso dell’istruzione CASE
PROGRAM data_successiva
! Questo programma legge giorno, mese ed anno di una data e determina
! la data successiva. Date possibili in ingresso: 1/1/1900 - 30/12/2000
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
INTEGER :: giorno, mese, anno
! dati in input
INTEGER :: giorni_del_mese
! dato da calcolare
! *** SEZIONE ESECUTIVA *** !
WRITE (*,*) 'Data (giorno, mese, anno)? '
READ (*,*) giorno, mese, anno
WRITE (*,*) 'Il giorno successivo al', giorno, '/', mese, '/', anno, '
e'':'
SELECT CASE (mese)
CASE (9,4,6,11)
giorni_del_mese = 30
CASE (1,3,5,7,8,10,12)
giorni_del_mese = 31
17
Calcolo della data del giorno successivo (cont.)
CASE (2)
IF (MOD(anno,4) == 0 .AND. anno /= 1900) THEN
giorni_del_mese = 29
ELSE
giorni_del_mese = 28
END IF
END SELECT
ultimo: IF (giorno == giorni_del_mese) THEN
giorno = 1
dicembre: IF (mese == 12) THEN
mese = 1
anno = anno + 1
ELSE
mese = mese + 1
END IF dicembre
ELSE
giorno = giorno + 1
END IF ultimo
WRITE (*,*) giorno, '/', mese, '/', anno
STOP
END PROGRAM data_successiva
18
Istruzioni di Ciclo
• Permettono di ripetere un insieme di
istruzioni finchè una certa condizione si
verifica.
• Cicli indefiniti: Il numero di ripetizioni non
è noto in anticipo
• Cicli definiti o iterativi: Il numero di
ripetizioni è noto prima dell’inizio del ciclo.
19
Cicli indefiniti: Ciclo WHILE
DO
istruzione 1
IF (espressione logica) EXIT
istruzione 2
END DO
• Quando la condizione di fine ciclo è vera, il
controllo passa all’istruzione successiva a END
DO.
• istruzione 1 viene eseguita almeno una
volta.
20
Calcolo della lunghezza
di una sequenza di interi
• Calcola la lunghezza di una sequenza di interi positivi
terminati da uno 0
• Gli interi sono letti in input uno ad uno finchè l’utente non
indica lo 0
21
Calcolo della lunghezza di una sequenza di interi (cont.)
! File: lung.for
! Scopo: primo esempio di uso di un ciclo di iterazione indefinita
PROGRAM calcola_lunghezza
IMPLICIT NONE
INTEGER :: lunghezza
!la lunghezza della sequenza
INTEGER :: dato
! il dato letto in input
WRITE(*,*) 'Inserisci una sequenza di interi, terminata da 0: '
lunghezza = 0
! all'inizio la lunghezza e' inizializzata a 0
DO ! iterazione indefinita
READ (*,*) dato
IF (dato == 0) EXIT
! condizione di uscita dal ciclo
lunghezza = lunghezza + 1
END DO
WRITE(*,*) 'La sequenza (senza lo 0 finale) e'' lunga ',lunghezza
STOP
END PROGRAM calcola_lunghezza
22
Calcolo del Massimo Comun Divisore
! File: mcd1.for
PROGRAM massimo_comun_divisore
! Questo programma legge due numeri interi a, b positivi e ne calcola
! il massimo comun divisore.
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
INTEGER :: a, b
! dati letti da tastiera
INTEGER :: mcd
! massimo comun divisore
LOGICAL :: trovato
! *** SEZIONE ESECUTIVA *** !
WRITE (*,*) 'Inserisci due interi positivi: '
READ (*,*) a, b
IF (a <= b) THEN
mcd = a
ELSE
mcd = b
END IF
trovato = .FALSE.
23
Calcolo del Massimo Comun Divisore (cont.)
DO
IF (mcd == 1 .OR. trovato) EXIT
IF (MOD(a,mcd) == 0 .AND. MOD(b,mcd) == 0) THEN
trovato = .TRUE.
ELSE
mcd = mcd - 1
END IF
END DO
WRITE (*,*) 'Massimo comun divisore di ', a, ' e ', b, ' : ', mcd
STOP
END PROGRAM massimo_comun_divisore
24
Calcolo della Media e della Varianza
• n numeri reali x1,…., xn.
1 n
• Media: X   x j
n j 1
2
n


2
n x j    x j 
j 1
j 1 

• Varianza:  
n
n(n  1)
25
Calcolo della Media e della Varianza (cont.)
! File: stat.for
PROGRAM media_varianza
! Questo programma calcola la media e la varianza di un insieme di
! dati positivi o nulli forniti in input
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
INTEGER :: n=0
! Numero di dati letti in input
REAL :: std_dev = 0
! Deviazione standard
REAL :: sum_x = 0
! Somma dei dati
REAL :: sum_x2 = 0
! Somma dei quadrati dei dati
REAL :: x
! Dato in input
REAL :: x_bar
! Media dei dati
26
Calcolo della Media e della Varianza (cont.)
! *** SEZIONE ESECUTIVA *** !
DO
WRITE (*,*) 'Digita il numero: (num<0 per uscire) '
READ (*,*) x
WRITE (*,*) 'Il numero e'':', x
IF (x < 0) EXIT
! Calcola le Somme
n = n + 1
sum_x = sum_x + x
sum_x2 = sum_x2 + x**2
END DO
27
Calcolo della Media e della Varianza (cont.)
! Controlla che i dati di input siano sufficienti
IF (n < 2) THEN
WRITE (*,*) 'Bisogna immettere almeno due valori.'
ELSE
x_bar = sum_x / real(n)
std_dev = sqrt ((real(n) * sum_x2 - sum_x**2) / (real(n) * real(n-1)))
WRITE (*,*) 'La media di questo insieme e'':', x_bar
WRITE (*,*) 'La deviazione standard
e'':', std_dev
WRITE (*,*) 'Il numero dei dati in input e'':', n
END IF
STOP
END PROGRAM media_varianza
28
Cicli Annidati
• All’interno di un’istruzione di ciclo si
possono eseguire altre istruzioni di ciclo
• E’ possibile associare un nome ad un ciclo:
nome:
DO
…..
IF (espressione logica ) EXIT nome
…..
END DO nome
29
Numeri perfetti
• Un numero perfetto è un numero somma di
tutti i suoi divisori ad esclusione del numero
stesso. Es: 6 = 1 + 2 + 3
• Per ogni intero positivo in input viene
verificato se il numero è perfetto
• Il ciclo DO esterno legge i dati in input, il
ciclo DO interno verifica se il numero è
perfetto.
30
Numeri Perfetti (cont.)
! File: perfetto.for
PROGRAM perfetto
! Questo programma determina se ogni intero positivo letto in input è
! perfetto
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
INTEGER :: dato
! dato in input
INTEGER :: somma = 1
! somma dei divisori
INTEGER :: i = 2
! potenziale divisore; si parte da 2
! *** SEZIONE ESECUTIVA *** !
!leggi: DO
WRITE (*,*) 'Inserisci valore (val <= 0 per uscire): '
READ (*,*) dato
IF (dato <= 0) EXIT leggi
WRITE(*,*) 'Divisori di', dato, ' (oltre a 1):'
31
Numeri Perfetti (cont.)
verifica: DO
IF (MOD(dato,i) == 0) THEN
IF (dato == i*i) THEN
WRITE (*,*) i
somma = somma + i
ELSE
WRITE (*,*) i, dato / i
somma = somma + i + dato / i
END IF
END IF
i = i + 1
IF (i*i > dato) EXIT verifica
END DO verifica
IF (somma == dato) THEN
WRITE (*,*) dato, ' E'' UN NUMERO PERFETTO'
ELSE
WRITE (*,*) dato, ' non e'' un numero perfetto'
END IF
END DO leggi
STOP
END PROGRAM perfetto
32
Cicli definiti: Ciclo DO
• Il numero di iterazioni è noto prima
dell’esecuzione dell’istruzione di ciclo
DO indice = inizio, fine, incremento
istruzione 1
…….
istruzione 2
END DO
33
Ciclo DO (cont.)
• inizio, fine, incremento: sono espressioni
calcolate prima dell’inizio del ciclo
• All’inizio:
indice = inizio
• Le istruzioni del corpo del ciclo sono eseguite se:
abs(indice) <= abs(fine)
• Dopo l’esecuzione delle istruzioni del ciclo:
indice = indice + incremento
34
Ciclo DO (Cont.)
• DO i = 1, 10, 2
istruzione 1
istruzione n
END DO
Il corpo del ciclo eseguito 5 volte
• DO i = 3, -3, -2
istruzione 1
istruzione n
END DO
Il corpo del ciclo eseguito 4 volte
35
Calcolo del Fattoriale
! File: fatt.for
! Scopo del programma è illustrare l’uso di cicli definiti
PROGRAM fatt
! Calcola il fattoriale di un intero
IMPLICIT NONE
INTEGER :: n, i , fattoriale
! Variabili che indicano l’intero, l’indice del ciclo ed il fattoriale
WRITE (*,*) 'Inserisci un intero: '
READ (*,*) n
fattoriale = 1
DO i=2, n
fattoriale = fattoriale * i
END DO
WRITE (*,*) 'Il fattoriale di', n, ' e'':', fattoriale
STOP
END PROGRAM fatt
36
Stampa di un Quadrato
! File: quadrato.for
! Scopo: illustrazione di un esercizio con cicli e stringhe
PROGRAM quadrato
! Questo programma legge un numero intero positivo n da tastiera e
! stampa un quadrato di asterischi di dimensione n
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
INTEGER, PARAMETER :: max_lunghezza = 25
! lunghezza massima del lato
INTEGER :: n
! dato letto da tastiera
INTEGER :: i
! indice dei cicli
CHARACTER(max_lunghezza) :: linea ! linea da stampare
37
Stampa di un Quadrato (cont.)
! *** SEZIONE ESECUTIVA *** !
WRITE (*,*) 'Dimensione del lato (lmin=1, lmax=25): '
READ (*,*) n
IF (n < 1 .OR. n > 25) THEN
WRITE (*,*) n, ' e'' un input non valido.'
ELSE
DO i = 1, n
linea(i:i) = '*'
END DO
DO i = n+1, max_lunghezza
linea(i:i) = ' '
END DO
DO i = 1, n
WRITE (*,*) linea
END DO
END IF
STOP
END PROGRAM quadrato
38
Cicli DO annidati: Calcolo della Tavola Pitagorica
! File: tavolpit.for
! Scopo: illustrare un programma con cicli annidati
PROGRAM tavola_pitagorica
! Questo programma legge un numero intero positivo n da tastiera e
! stampa tutti i prodotti i * j (1 <= i,j <= n), uno per riga
IMPLICIT NONE
INTEGER :: n
INTEGER :: i,j
! il dato letto da tastiera
! indici dei cicli
WRITE (*,*) 'Inserisci un intero positivo: '
READ (*,*) n
WRITE (*,*) 'Tavola pitagorica da 1 a ', n, ': '
esterno: DO i = 1, n
interno: DO j = 1, n
WRITE (*,*) i, ' * ', j, ' = ', i*j
END DO interno
END DO esterno
STOP
END PROGRAM tavola_pitagorica
39
Traiettoria di un proiettile
• Traiettoria parabolica di un proiettile sparato con velocità
iniziale v0 e angolo theta dalla posizione (0,0)
• vx = v0 * COS(theta)
vy = v0 * SIN(theta)
• Altezza dal suolo al tempo t:
y(t) = vy * t + 1/2 * g * t**2
• Distanza orizzontale percorsa al tempo t
x(t) = vx * t
• Data la velocità v0, determinare:
– la gittata (distanza orizzontale del proiettile prima di toccare terra)
al variare di theta tra 0° e 90° con step di 1°.
– l’angolo theta per cui la gittata è massima.
40
Calcolo della gittata
• Tempo di atterraggio:
vy * t + 1/2 * g * t**2 = 0
t1 = 0, t2 = - 2 * vy / g
• range = vx t2 = - 2 * vx * vy / g
= - 2 v0**2 * COS(theta) *
SIN(theta) /g
41
Traiettoria di un proiettile (cont.)
! File: gittata.for
PROGRAM gittata
! Scopo: Calcolare la distanza percorsa da un proiettile sparato con
! angolo theta e velocità v = 20 m/s
! *** SEZIONE DICHIARATIVA *** !
IMPLICIT NONE
REAL, PARAMETER :: gradi_a_rad = 0.01745329
! Conversione da gradi a radianti
REAL, PARAMETER :: gravity = -9.81
INTEGER :: max_degrees ! Angolo di massima gittata
REAL :: max_range
! Massima gittata alla velocita’ v0
REAL :: range
! Gittata con un dato angolo
REAL :: radian
! Angolo iniziale in radianti
INTEGER :: theta
! Angolo iniziale in gradi
REAL :: v0
! Velocita’ del proiettile
42
Traiettoria di un proiettile (cont.)
! *** SEZIONE ESECUTIVA *** !
max_range = 0.
max_degrees = 0
v0 = 20.
loop: DO theta = 0, 90
radian = real(theta) * gradi_a_rad
range = - 2. * v0**2 * COS(radian) * SIN(radian) / gravity
WRITE (*,*) 'THETA =', theta, ' gradi; Gittata =', range, ' metri'
IF (range > max_range) THEN
max_range = range
max_degrees = theta
END IF
END DO loop
WRITE (*,*) 'Gittata massima = ', max_range, ' a', max_degrees, '
gradi'
STOP
END PROGRAM gittata
43
Esercizi
• Scrivere un programma che calcoli il massimo di una sequenza di
interi positivi dati in input e terminati da uno 0.
• Scrivere un programma che dato in input un intero n stampi un
triangolo equilatero di asterischi. Ad esempio per n=5:
*
**
***
****
*****
• Disegnare la traiettoria di un proiettile sul piano cartesiano
44
Scarica

2. Istruzioni di Controllo