LABORATORIO di INFORMATICA

Transcript

LABORATORIO di INFORMATICA
Università degli Studi di Cagliari
Corso di Laurea Magistrale in Ingegneria per l’Ambiente ed il Territorio
LABORATORIO
di INFORMATICA
A.A. 2010/2011
Prof. Giorgio Giacinto
STRUTTURE DI CONTROLLO IN C
http://www.diee.unica.it/giacinto/Lab
Introduzione
!
!
Caratteristica essenziale degli algoritmi
le operazioni da applicare possono dipendere dallo
stato di esecuzione dell’algoritmo stesso
Nella macchina di Von Neumann
!
!
!
!
test su un registro
l’esito del test determina il valore del registro Program
Counter (PC)
il nuovo valore del registro PC può non essere consecutivo al
precedente: salto di istruzioni
Nel C esistono altre strutture di controllo oltre a ifelse e while
Giorgio Giacinto 2010
Laboratorio di Informatica
2
Teorema di Boehm-Jacopini
Le strutture di controllo if-else e while sono
equivalenti alle strutture di controllo del linguaggio
assemblatore basate sulla manipolazione diretta e
condizionale del registro Program Counter
!
!
tutti gli algoritmi che possono essere codificati con
una, possono essere codificati con l’altra e viceversa
sono equivalenti alle strutture di controllo di qualsiasi
altro linguaggio di programmazione
Sono complete nel senso che ognuna di esse è
sufficiente per codificare qualsiasi algoritmo
Giorgio Giacinto 2010
Laboratorio di Informatica
3
Strutture di controllo nel C
!
!
Pur essendo if-else e while sufficienti
per codificare qualsiasi algoritmo, il
linguaggio C mette a disposizioni altre
strutture di controllo per semplificare l’attività
del programmatore
In altre parole le ulteriori strutture di controllo
del C offrono una alternativa all’uso di ifelse e while in alcuni casi particolari.
Giorgio Giacinto 2010
Laboratorio di Informatica
4
Istruzioni di selezione
!
!
L’istruzione condizionale if-else è costruita per
scegliere l’esecuzione di un’istruzione in alternativa
a un’altra a seconda del valore assunto da una
condizione
Nel caso di alternative molteplici il C offre strutture di
controllo di tipo selettivo
!
Ad esempio, l’utente è invitato a scegliere fra diverse
opzioni usando caratteri diversi della tastiera
In questi casi si dovrebbero usare costrutti if-else annidati
Giorgio Giacinto 2010
Laboratorio di Informatica
5
Il costrutto switch
L’istruzione switch si presta a identificare la scelta di
un’istruzione tra altre sulla base del valore di una
particolare variabile o espressione
switch(<espressione>):
{
{case <espressione costante>: [<sequenza_istruzioni>]
[break;]}
[default: [<sequenza_istruzioni>]]
}
!
Giorgio Giacinto 2010
Laboratorio di Informatica
6
Il costrutto switch (cont.)
!
!
Ciascuna clausola case può essere seguita o no
dalla corrispondente sequenza di istruzioni da
eseguire
Le istruzioni dopo un case sono separate fra loro da
; ma non sono racchiuse fra parentesi graffe
!
!
Entrati in un case, vengono eseguite in sequenza tutte le
istruzioni
L’istruzione break fa uscire dal costrutto switch
!
Le eventuali clausole successive non vengono valutate e si
salta alla prima istruzione esterna al costrutto switch
Giorgio Giacinto 2010
Laboratorio di Informatica
7
Il costrutto switch (cont.)
!
!
La parola chiave default individua l’eventuale
sequenza di istruzioni da eseguire se la valutazione
dell’espressione determina un valore che non è
contemplato dai case.
Funzionamento di switch
!
!
SI valuta l’espressione (deve essere di tipo integral)
Il valore ottenuto viene confrontato con il valore costante di
ciascun case
! se viene soddisfatta una clausola case, vengono eseguite
tutte le istruzioni successive (anche se appartengono a
case diversi!); break interrompe la sequenza
! opzionale, le istruzioni da eseguire negli altri casi
(default)
Giorgio Giacinto 2010
Laboratorio di Informatica
8
Esempi del costrutto switch
switch (CarattereLetto)
{
case ‘A’: case ’G’: case ‘H’:
printf(“Il carattere letto e’ A o G o H\n”);
break;
case ‘F’: printf(“Il carattere letto e’ F\n”);
break;
default:
printf(“Il carattere letto e’ sbagliato\n”);
}
NOTA: la clausola default potrebbe non essere presente:
dipende dal funzionamento desiderato del programma
Giorgio Giacinto 2010
Laboratorio di Informatica
9
Osservazioni sul costrutto
switch
!
Nell’uso del costrutto switch
!
!
!
Evitare ambiguità: le espressioni delle clausole
case devono essere costanti e diverse tra loro
Inserire l’istruzione default per assicurare il
trattamento completo dei diversi casi
Inserire l’istruzione break alla fine dell’ultima
istruzione case per rendere il codice facilmente
estensibile nel caso di aggiunta a posteriori di
altre istruzioni case
Giorgio Giacinto 2010
Laboratorio di Informatica
10
(1) Melodia dal nome
!
!
Leggere i caratteri del nome dell’utente
Trasformare ciascun carattere in una nota musicale
con le seguenti regole
!
!
!
Si considera il codice ASCII del carattere
Si considera il resto della divisione per 7
Le note sono associate ai numeri da 0 a 6 nel modo
seguente:
Do (0), Re (1), Mi (2), Fa (3), Sol (4), La (5), Si (6)
N.B. Per semplicità si sono considerate solo le 7 note naturali
Il carattere # termina la sequenza di immissione
Giorgio Giacinto 2010
Laboratorio di Informatica
11
(1) Melodia dal nome (cont.)
char C;
int
resto;
printf(“Inserisci il primo carattere del tuo nome\n”);
scanf(“%c”,&C);
while(C != ‘#’)
{
resto = C % 7;
switch (resto)
{
case 0: printf(“Il carattere %c corrisponde alla nota
‘do’\n”);
break;
..........
}
printf(“Inserisci il prossimo carattere del tuo nome (#
per terminare)”);
scanf(“%c”,&C);
}
Giorgio Giacinto 2010
Laboratorio di Informatica
12
Altri tipi di alternative multiple
!
!
In C if-else e switch vengono utilizzate anche
quando le azioni da scegliere sono molteplici ma il
criterio di scelta non può essere espresso in termini
del valore di un’espressione
In mancanza di costrutti adeguati si può migliorare
la leggibilità del programma con particolari stili di
programmazione
!
Es.
Giorgio Giacinto 2010
if (<Condizione>)
else if (<Condizione>)
else if (<Condizione>)
else <Espressione>;
<Espressione>;
<Espressione>;
<Espressione>;
Laboratorio di Informatica
13
Istruzioni cicliche
il ciclo for
!
Il ciclo for può sostituire i costrutti while del tipo
VarDiConteggio = ValoreIniziale;
while (VarDiConteggio <= ValoreFinale)
{
[Sequenza di istruzioni da ripetere];
VarDiConteggio = VarDiConteggio + 1;
}
!
[Sequenza di istruzioni da ripetere] rappresenta il corpo del
ciclo
NOTA: il ciclo for consente anche altri utilizzi che non verranno trattati in questo corso
Giorgio Giacinto 2010
Laboratorio di Informatica
14
Istruzioni cicliche
il ciclo for (cont.)
Sintassi
for(<espressione>;<espressione>;<espressione>)
<sequenza istruzioni>
!
Di solito
la prima espressione esprime l’assegnamento del valore
iniziale della variabile di conteggio
la seconda espressione esprime la condizione che
determina l’esecuzione del ciclo (il corpo del ciclo viene
eseguito se ‘vera’)
la terza espressione viene eseguita come ultima
espressione del corpo del ciclo e incrementa o
decrementa la variabile di conteggio
Giorgio Giacinto 2010
Laboratorio di Informatica
15
Istruzioni cicliche
il ciclo for (cont.)
Un ciclo di conteggio In C si esprime come
for (i = ValIniz; i <= ValFin; i++)
<sequenza istruzioni >
dove i indica una generica variabile intera usata per il conteggio
! L’operatore ++ (--) autoincremento (autodecremento)
!
!
Incrementa (decrementa) di una unità il valore della
variabile
Può essere preposto o postposto all’identificatore di
variabile:
3 * i++; equivale a 3*i; i = i +1;
3 * ++i; equivale a i = i + 1; 3 * i;
Giorgio Giacinto 2010
Laboratorio di Informatica
16
(2) Conta caratteri in un testo
Come esempio dell’uso del ciclo for, si conti quante
volte ogni lettera dell’alfabeto compare in un testo
costituito da una sequenza di parole separate tra loro
da uno o più spazi (senza segni di interpunzione) e
terminato dal carattere speciale \0.
Vedi il file Contacar.c
Per esercizio, sostituire i cicli while usati negli esempi precedenti con dei cicli for.
Giorgio Giacinto 2010
Laboratorio di Informatica
17
Istruzioni cicliche
il ciclo do-while
Sintassi
do
<sequenza istruzioni>
while(<espressione>);
<espressione> è un’espressione booleana
! Il corpo di un ciclo di questo tipo viene
comunque eseguito almeno una volta, e
ripetuto fintantoché la condizione indicata
dopo il while è vera.
Giorgio Giacinto 2010
Laboratorio di Informatica
18
Esempio
lettura testo con while
Lettura di una sequenza di caratteri, non contenenti alcun
‘a capo’ e terminata dal carattere % e memorizzazione
(ultimo carattere incluso) in un array di caratteri.
*Soluzione con ciclo while*
Contatore = 0; scanf(“c”,&Dato);
while(Dato==‘\n’||Dato==‘\r’) scanf(“%c”,&Dato);
Testo[Contatore]=Dato;
while(Dato!=‘%’ && Contatore < LungMax)
{
Contatore++; scanf(“%c”,&Dato);
while(Dato==‘\n’||Dato==‘\r’) scanf(“%c”,&Dato);
Testo[Contatore]=Dato;
}
Giorgio Giacinto 2010
Laboratorio di Informatica
19
Esempio
lettura testo con do-while
Esempio precedente con do-while
Contatore = 0;
do
{
do
scanf (“%c”, &Dato);
while(Dato == ‘\n’ || Dato == ‘\r’);
Testo[Contatore]= Dato;
Contatore++;
} while(Dato != ‘%’ && Contatore <
LungMax);
Giorgio Giacinto 2010
Laboratorio di Informatica
20
Istruzione goto
Il linguaggio C mantiene tra le strutture di controllo
istruzioni di salto ispirate dai linguaggi di basso livello
Esempio:
scanf (“%d”, &x, &y);
if (y == 0) goto error;
printf (“%f\n”, x/y);
...
error: printf(“y non può essere uguale a 0\n”);
L’esecuzione di goto provoca il salto all’istruzione etichettata da
error
L’uso di goto nel linguaggio C è sconsigliato!
Si utilizzano le strutture di controllo di alto livello illustrate in questo
modulo
Giorgio Giacinto 2010
Laboratorio di Informatica
21
Istruzioni break e continue
!
Due istruzioni in C sono in grado di
interrompere il flusso di controllo: break e
continue
!
break causa la fuoriuscita dal corpo di un
ciclo o da una istruzione di switch
continue causa l’interruzione della corrente
iterazione del ciclo e dà l’inizio all’iterazione
successiva di un ciclo while, do o for
!
Giorgio Giacinto 2010
Laboratorio di Informatica
22
Esempi: break e continue
while (true)
{
scanf (“%d%d”, &x, &y);
if (x == 0)
break; /* Interrompe un ciclo infinito */
printf (“%f\n”, x/y);
}
for (i = 0; i < NumDati; i++)
{
do scanf (“%c”, &Dato);
while
(Dato == ‘\n’ || Dato == ‘\r’);
if ((Dato >= ‘A’ && Dato <= ‘Z’) ||
(Dato>=‘a’ && Dato <= ‘z’)) continue;
/* Salta tutte le istruzioni successive
...
e riprende da i++ del ciclo for */
}
Giorgio Giacinto 2010
Laboratorio di Informatica
23