INFORMATICA
Strutture condizionali
Strutture condizionali
• Sono le istruzioni che rappresentano il ben noto costrutto
IF – THEN – ELSE della programmazione strutturata.
• In C, come peraltro in tutti gli altri linguaggi, è disponibile
in tre forme:
- if (then)
- if (then) else
- switch
(in altri linguaggi noto come CASE)
© Piero Demichelis
2
L’istruzione if
• Permette di eseguire una istruzione, semplice o composta, in modo
condizionato. Sintassi:
if (espressione) istruzione ;
• espressione è di tipo logico (variabile o espressione logica o
espressione relazionale con risultato logico) e deve essere sempre
racchiusa tra parentesi tonde; istruzione può essere semplice o
composta (nel qual caso va racchiusa tra parentesi graffe).
• Pertanto, più comunemente, la forma è:
if ( espressione )
{
istruzione semplice o composta ;
}
© Piero Demichelis
3
L’istruzione if
• Il significato è: valuta espressione e, se il risultato è vero,
esegui istruzione, altrimenti ignorala e prosegui con
l'istruzione immediatamente successiva all’if .
• Il fatto che espressione debba fornire un risultato di tipo
logico significa solo che deve fornire un risultato intero!
• Si ricordi che in C89 il tipo logico è simulato dal tipo
intero.
• In definitiva dunque per espressione è accettabile
qualsiasi cosa fornisca un risultato intero: sarà
interpretata come falsa se il suo valore risulta 0, vera se il
suo valore risulta diverso da 0.
© Piero Demichelis
4
L’istruzione if
• Il fatto che la valutazione della condizione si riduca in
definitiva a un test per vedere se vale 0 oppure un valore
intero diverso da 0 comporta che, se a è una variabile
dichiarata intera (int oppure long int), le seguenti
istruzioni:
- if ( a != 0 ) { .....
- if ( a ) { .....
siano assolutamente equivalenti. Infatti qualsiasi valore di
a diverso da 0 rende la condizione vera in entrambi i casi.
© Piero Demichelis
5
Istruzione if
• Questo costrutto realizza la struttura IF – THEN della
programmazione strutturata: l'unica differenza è l'assenza
della parola chiave THEN qui sottintesa.
• Diagramma di flusso:
V
I
espressione
F
istruzione
O
© Piero Demichelis
6
Istruzione if: esempio
• Realizzare un programma che richieda da tastiera due
numeri interi e visualizzi sul monitor il massimo dei due.
• Il problema si può risolvere con un semplice if:
-
Legge da tastiera i due numeri chiamandoli x e y;
Ipotizzo che x sia il più grande;
Se y è più grande di x allora scambio tra loro i valori di x e y;
Stampa il valore di x (che contiene sicuramente il valor massimo).
• Per scambiare tra loro i valori di x e y:
- salvo il valore di x in una variabile di appoggio (provv
- copio y in x (x
y);
- copio provv in y (y
provv).
© Piero Demichelis
x);
7
Istruzione if: esempio
#include <stdio.h>
main()
{
float x, y, provv;
printf (“\nIntroduci due numeri reali: ");
scanf ("%f%f", &x, &y);
if (y > x)
{
provv = x;
x = y;
/* scambia x e y tra loro */
y = provv;
}
printf ("\nIl maggiore è %f il minore è %f", x, y);
}
© Piero Demichelis
8
Osservazioni su if
• Attenzione a scrivere un’istruzione di questo tipo:
if ( a = 0 ) {.....
dove quasi certamente si intendeva porre la condizione di
a uguale a zero.
• Purtroppo la sintassi per realizzare quell’espressione
relazionale è sbagliata (si doveva scrivere a == 0) ma
l’istruzione in se è formalmente corretta per cui il
compilatore non genera errore (al più qualche
compilatore segnala un warning).
© Piero Demichelis
9
Istruzione if ... else
• Consente di eseguire una istruzione (semplice o
composta) oppure un'altra istruzione (anch’essa semplice
o composta) a seconda del verificarsi o meno di una certa
condizione.
• Sintassi:
if (espressione) istruzione 1; else istruzione 2;
• espressione è una variabile logica o una espressione con
risultato logico racchiusa tra parentesi tonde;
• istruzione 1 e istruzione 2 possono essere semplici o
composte (ovvero un gruppo di istruzioni racchiuse tra
parentesi graffe).
© Piero Demichelis
10
Istruzione if ... else
• Più comunemente nei programmi si usa la forma estesa e
più leggibile dell’istruzione:
if (espressione)
{
istruzione semplice o composta 1 ;
}
else
{
istruzione semplice o composta 2 ;
}
© Piero Demichelis
11
Istruzione if ... else
• Significato: valuta espressione e, se il risultato è vero,
esegui istruzione 1 e ignora istruzione 2 , altrimenti
ignora istruzione 1 ed esegui istruzione 2.
• Questo costrutto realizza la struttura IF - THEN – ELSE
della programmazione strutturata: anche in questo caso
se ne differenzia per l’assenza della parola chiave THEN
qui sottintesa.
• Poiché non esistono limitazioni a istruzione, queste
possono contenere qualsiasi costrutto, compresi altri if
(si parla allora di if annidati ).
© Piero Demichelis
12
Istruzione if ... else
Diagramma di flusso:
I
V
espressione
istruzione 1
F
istruzione 2
O
© Piero Demichelis
13
Istruzione if ... else: esempio 1
• Realizzare un programma che richieda da tastiera due
numeri interi e visualizzi sul monitor il massimo dei due.
• Il problema si risolve con un if ... else (non considerando
il caso x = y):
- Legge da tastiera i due numeri chiamandoli x e y;
- Se x è più grande di y allora visualizza x ;
altrimenti visualizza y.
© Piero Demichelis
14
Istruzione if ... else: esempio 1
#include <stdio.h>
main()
{
float x, y;
printf (“\nIntroduci due numeri reali: ");
scanf ("%f%f", &x, &y);
if (x > y)
printf (“\nIl maggiore è: %f ”, x);
else
printf (“\nIl maggiore è: %f ”, y);
}
© Piero Demichelis
15
Istruzione if ... else: esempio 2
• Realizzare un programma che calcoli quoziente e resto di
due numeri interi positivi letti da tastiera e segnali errore
se uno dei due è negativo (attenzione alla divisione per
zero!).
• Pseudocodice:
- Legge i due numeri da tastiera e li chiama n1 e n2;
- Se n1 e n2 sono entrambi positivi e n2 è diverso da 0:
• calcola il quoziente ( n1 / n2);
• calcola il resto (n1 % n2);
• visualizza quoziente e resto;
altrimenti
• visualizza messaggio d’errore.
© Piero Demichelis
16
Istruzione if ... else: esempio 2
#include <stdio.h>
main()
{
int n1, n2, quoz, resto;
printf ("\nIntrodurre due numeri interi: ");
scanf ("%d%d", &n1, &n2);
if ((n1 >= 0) && (n2 > 0))
{
quoz = n1 / n2;
resto = n1 % n2;
/* oppure resto = n1 - (quoz * n2); */
printf (“\nQuoziente= %d, resto= %d\n", quoz, resto);
}
else
printf (“\nErrore nei dati");
}
© Piero Demichelis
17
Istruzione if ... else: esempio 3
• Leggere due valori A e B, e calcolarne la differenza in valore assoluto :
D = |A-B|
• Soluzione
#include <stdio.h>
main()
{
int a, b, differenza;
printf (“\nIntroduci i 2 valori (a e b): “);
scanf (“%d%d”, &a, &b);
if (a >= b)
differenza = a - b;
else
differenza = b - a;
printf (“\nValore assoluto: %d”, differenza);
}
© Piero Demichelis
18
Istruzione if ... else: osservazioni
• L'istruzione che precede l'else deve essere chiusa
normalmente con il punto e virgola. L'else infatti fa parte
della struttura if ... else e non entra in gioco nell'analisi
sintattica dell'istruzione che la precede, la quale deve
avere quindi una chiusura regolare.
• Negli if annidati possono sorgere delle ambiguità. Ad
esempio nel costrutto:
if (espressione 1) if (espressione 2) istruzione 1; else istruzione 2;
non è chiaro se l'else appartiene all'if più interno o più
esterno.
• L'uso delle parentesi { e } può dirimere qualsiasi dubbio.
© Piero Demichelis
19
Istruzione if ... else: osservazioni
• La precedente istruzione può essere riscritta come:
if (espressione 1)
{
if (espressione 2)
istruzione 1;
else
istruzione 2;
}
else appartenente all’if interno
• oppure:
if (espressione 1)
{
if (espressione 2)
istruzione 1;
}
else
istruzione 2;
else appartenente all’if esterno
© Piero Demichelis
20
Istruzione if ... else: osservazioni
• Non conviene usare if annidati su troppi livelli: si
introducono difficoltà in fase di test (debugging) e
rallentamenti nell'esecuzione del programma.
• Inoltre sono da evitare istruzioni del tipo:
if (dato1 == dato2)
flag = VERO;
else
flag = FALSO;
che possono essere sostituite più elegantemente dalle
assegnazioni:
flag = (dato 1 == dato2);
© Piero Demichelis
21
Esempio: equazione di II grado
• L’applicazione classica della struttura if ... else è la
soluzione completa dell’equazione di II grado.
• La soluzione è fornita da un costrutto if ... else nel quale
sono annidati altre strutture di tipo if ... else e if che
risolvono i vari rami secondari.
• La soluzione deve tener conto di tutti i possibili casi che
possono determinarsi nella soluzione (equazione
impossibile, indeterminata, di I grado, ecc.).
© Piero Demichelis
22
Equazione di II grado
Legge i coefficienti a, b e c
si
a = 0?
no
b = 0?
delta = b*b – 4*a*c
no
w = 2*a
w1= -(b / w)
c = 0?
Equazione di I grado:
si
no
x= -(c / b)
delta = 0?
no
si
Equazione
Equazione
indeterminata
impossibile
Radice doppia
w2= | delta | / w
x = w1
delta < 0?
no
si
si
Radice reali:
x1= w1+ w2 x2= w1- w2
© Piero Demichelis
Radice complesse
coniugate: x = w1± j w2
23
Istruzione switch
• Quando la condizione da imporre non è intrinsecamente
binaria ma si deve distinguere tra più casi ed eseguire le
istruzioni approppriate per ogni singolo caso, l‘if annidato
può non essere più conveniente per complessità, leggibilità
e, qualche volta, anche per tempo di esecuzione
(valutazione di n condizioni).
• Per questi casi c‘è l'istruzione switch.
© Piero Demichelis
24
Istruzione switch
Diagramma di flusso:
caso 1
caso 2
I
caso n
espressione
caso 3
istr. 1
istr. 2
.................
istr. 3
istr. n
O
© Piero Demichelis
25
Istruzione switch
• Sintassi:
switch (espressione)
{
case <costante 1>:
<istruzione 1>
break;
case <costante 2>:
<istruzione 2>
break;
...
...
[ default:
< istruzione default> ]
}
© Piero Demichelis
26
Istruzione switch
- espressione : espressione a valore numerico di tipo int o char, ma
non float o double.
- <costante1>, <costante1>, ... sono costanti dello stesso tipo
dell'espressione
- <istruzione 1>, <istruzione 2>, .... sono sequenze di istruzioni
(senza graffe!)
• Significato:
- In base al valore di espressione, esegui le istruzioni del case
corrispondente.
- Nel caso nessun case venga intercettato, esegui le istruzioni
corrispondenti al caso default (se esiste).
© Piero Demichelis
27
Istruzione switch: osservazioni
• I vari case devono rappresentare condizioni
MUTUAMENTE ESCLUSIVE!
• I vari case vengono eseguiti in sequenza, uno dopo
l’altro: per evitarlo è necessario interrompere il flusso
usando l’istruzione break alla fine di ogni blocco di
istruzioni (il flusso prosegue con la prima istruzione
successiva alla switch).
• Se il blocco di default non è presente e nessun case viene
soddisfatto, l’esecuzione procede con la prima istruzione
che segue la switch.
© Piero Demichelis
28
Istruzione switch: esempio
main()
{
int x;
printf (“\nIntroduci un numero intero: “);
scanf (“%d”, &x);
switch (x) {
case 1:
printf(“\nHai introdotto 1“);
break;
case 2:
printf(“\nHai introdotto 2“);
break;
default:
printf(“\nHai introdotto un numero diverso da 1 e 2“);
}
}
© Piero Demichelis
29
Osservazioni su switch
• I case possono essere indicati nell’ordine che si desidera e non in
ordine strettamente crescente o decrescente.
main()
{ int x;
printf (“\nIntroduci un numero intero: “);
scanf (“%d”, &x);
switch (x) {
case 92:
printf(“\nHai introdotto 92“);
break;
case -14:
printf(“\nHai introdotto -14“);
break;
case 36:
printf(“\nHai introdotto 36“); }
}
© Piero Demichelis
30
Scarica

I costrutti condizionali