Fondamenti di Programmazione
Prof. A. Della CioppaHello Dave
Lecture Plan
๏ Funzioni di Input e Output
๏ Strutture selettive ed iterative
Lecture Plan
๏ Funzioni di Input e Output
๏ Strutture selettive ed iterative
stdin
stderr
stdout
Stream
stdin
stderr
stdout
Stream preesistenti
๏ Quando un programma viene mandato in esecuzione, il sistema operativo gli fornisce 3 stream (flussi di dati) già aperti (pronti per essere usati)
stdin
stderr
stdout
Stream preesistenti
๏ stdin [standard input] collegato alla tastiera
๏ stdout [standard output] collegato al video per l’output normale, ossia per m o s t r a r e i d a t i p r o d o t t i dall’elaborazione
๏ stderr [standard error] collegato al video per l’output di diagnostica, ossia per riportare informazioni relative al funzionamento del programma, come la segnalazioni errori.
stdin
stderr
stdout
Funzioni di I/O
๏ Per utilizzare le funzioni di I n p u t / O u t p u t b i s o g n a includere il file di intestazione (header file) denominato
<stdio.h>
๏ Per l’inclusione si usa la direttiva #include
#include <stdio.h>
stdin
stderr
stdout
Funzioni di I/O
๏ <stdio.h> contiene la sintassi d’uso delle funzioni per mezzo dei prototipi delle funzioni (descritti in a l t re s l i d e ) i n m o d o c h e i l compilatore possa controllare che l’utilizzo delle funzioni sia corretto
๏ <stdio.h> contiene anche la definizione di alcune costanti simboliche (#define), tra queste la EOF usata da alcune funzioni per segnalare la fine dell’input o del file usato in I/O.
stdin
stderr
stdout
Input
scanf
stdin
stderr
stdout
Input formattato: scanf
๏ La scanf è la più completa tra le funzioni di input da tastiera (scan formatted = scansione con formato)
๏ Sintassi:
scanf(“stringa formato”, lista di variabili)
๏ Legge valori dalla tastiera e li assegna alle variabili indicate nella lista di variabili
๏ Per ciascuna variabile c’è il corrispondente tipo nella stringa formato
scanf("%d%d", &a, &b);
Input formattato: scanf
scanf(“stringa formato”, lista di variabili)
๏ La lista di variabili è un elenco di variabili a cui assegnare i dati letti dalla tastiera:
๏ sono separate da virgole
๏ sono assegnate nell’ordine in cui sono elencate precedute (ciascuna) dal carattere & per indicarne l’indirizzo in memoria
๏ La stringa formato contiene un elenco di specifiche di conversione:
๏ sono composte da una lettera preceduta dal carattere %
๏ specificano il tipo di dato atteso per ciascuna delle variabili della lista di variabili
Input formattato: scanf
๏ Specifiche di conversione:
Tipo Formato
%d int
%u unsigned int
%x unsigned int (hex)
%hd short int
%ld long int
%lu unsigned long int
%f, %e, %g float
%lf double
%Lf long double
%c char
%s stringa
stdin
stderr
stdout
Input formattato: scanf
๏ Esempi:
scanf("%d", &a);
legge 1 valore di tipo int (come richiesto dalla specifica %d) e lo assegna alla variabile a (che deve essere stata definita di tipo int).
scanf("%d%d", &a, &b);
legge 2 valori di tipo int e li assegna ad a e b (di tipo int) Quest’ultima equivale a:
scanf("%d", &a);
scanf("%d", &b);
Input formattato: scanf
๏ Tipicamente la stringa di formato contiene solo specifiche di conversione, senza altri caratteri in mezzo (neppure spazi): "%d%d%d"
๏ La stringa di formato può contenere anche caratteri ordinari, in questo caso la scanf si aspetta l’introduzione proprio di quei caratteri in quella esatta sequenza.
๏ I caratteri letti sono scartati ad uno ad uno finché corrispondono a quelli indicati nella stringa di formato, quando si verifica una non corrispondenza la scanf termina e rimette l’ultimo carattere a disposizione delle prossime letture.
Input formattato: scanf
๏ Ad esempio
scanf("%d/%d/%d", &giorno, &mese, &anno);
legge date tipo “25/2/1997”, ma in un input quale “25 febbraio 1997” fa leggere solo il 25 e al primo spazio si ferma, la successiva lettura riprende da questo spazio (incluso).
Input formattato: scanf
๏ Nella stringa di formato i white space (tra cui: spazio, Tab e ‘\n’) sono caratteri ordinari gestiti in modo diverso.
๏ Un qualsiasi white space nella stringa formato indica alla scanf che ci si aspetta di trovare uno o più white space (di qualunque tipo) consecutivi in quel punto dell’input (da scartare).
๏ Errore frequente è indicare il carattere ‘\n’ nella stringa di formato pensando di passare così alla lettura della riga successiva.
scanf(“%d\n%d”, &a, &b);
Errore!
Input formattato: scanf
๏ La scanf legge da tastiera dei caratteri e in base alla specifica di conversione ‘%x’ e li trasforma in u n v a l o r e d e l t i p o corrispondente. Il gruppo di caratteri letti di volta in volta dalla scanf viene detto campo (field).
๏ La scanf salta i white space iniziali del campo che legge (è per questo che i valori possono essere immessi su più righe).
stdin
stderr
stdout
Input formattato: scanf
๏ Il numero di caratteri usati per costituire un campo dipende dalla specifica di conversione:
๏ viene prelevato il massimo numero di caratteri compatibili con il tipo richiesto dalla specifica
๏ non appena si incontra un carattere non compatibile con la specifica si ferma
๏ i caratteri rimanenti rimangono a disposizione per le successive letture (“restano nel buffer della tastiera”, ossia in memoria)
stdin
stderr
stdout
Input formattato: scanf
๏ Se si inserisce dalla tastiera la sequenza di caratteri “12 23 34”, una scanf("%d", &a); legge il 12 e lo mette in a, mentre “ 23 34” resta in memoria e verrà utilizzato (ad es.) dalla successiva scanf
๏ Se non ci sono caratteri compatibili con il tipo richiesto dalla specifica, il c a m p o è n u l l o , l a v a r i a b i l e corrispondente non viene modificata, la scanf termina immediatamente e tutti i caratteri restano nel buffer di tastiera
stdin
stderr
stdout
Input formattato: scanf
๏ Se si inserisce dalla tastiera la sequenza di caratteri
“12 abc 34”
scanf("%d%d", &a, &b);
๏ legge solo il 12 perché si aspetta un valore numerico per b e invece trova “ abc 34”
che non lo è, il contenuto di b non viene modificato
stdin
stderr
stdout
Input formattato: scanf
๏ La funzione scanf restituisce:
๏ un valore ≥ 0 di tipo int che indica a quante variabili della lista sono stati assegnati valori prelevati dalla tastiera
๏ oppure il valore int costante EOF che indica che si è verificato un errore o che non c’è nulla da leggere
n = scanf("%d%d", &a, &b);
stdin
stderr
stdout
Output
printf
stdin
stderr
stdout
Output formattato: printf
๏ La printf è la più completa tra le funzioni di output da tastiera (print formatted = scansione con formato)
๏ Sintassi:
printf(“stringa formato”, lista delle espressioni);
๏ Stampa a video i valori nella lista delle espressioni in accordo alla stringa formato
๏ Ciascun valore della lista di espressioni viene visualizzato sostituendolo alla corrispondente direttiva di conversione nella stringa di formato
printf("Area: %d, Perimetro: %d\n", a, b);
Input formattato: printf
printf(“stringa formato”, lista delle espressioni);
๏ La lista di espressioni è l’elenco delle espressioni di cui visualizzare il risultato:
๏ ciascun risultato viene visualizzato al posto della corrispondente specifica di conversione (devono corrispondere per numero e tipo)
๏ le espressioni sono separate da virgole
๏ La stringa formato contiene un elenco di specifiche di conversione:
๏ caratteri ordinari, vengono visualizzati tali e quali (per visualizzare il carattere %, lo si deve indicare raddoppiato: %%)
๏ specifiche di conversione (es. %d) che indicano come visualizzare l’espressione corrispondente della lista di espressioni
Input formattato: printf
๏ P r i n c i p a l i s p e c i fi c h e d i conversione:
Tipo Formato
%d int
%u unsigned int
%x unsigned int (hex)
%hd short int
%ld long int
%lu unsigned long int
%f, %e, %g float
%lf double
%Lf long double
%c char
%s stringa
stdin
stderr
stdout
printf : Sequenze di escape
๏ Le sequenze di escape permettono di inserire singoli caratteri speciali nella stringa di formato:
๏ \n inserisce un ritorno a capo (si mette in fondo)
๏ \t inserisce un carattere Tab
๏ \" inserisce un carattere doppie virgolette "
๏ \’ inserisce un carattere apice ’
๏ \\ inserisce un carattere backslash \
stdin
stderr
stdout
Input formattato: printf
๏ printf restituisce un valore int che può essere:
๏ ≥ 0: coincide con il numero di caratteri scritti a video
๏ < 0: è una segnalazione di un errore
n = printf("Somma=%d", a);
Con a pari a 5, n vale 9.
stdin
stderr
stdout
Input formattato: printf
๏ Tra il carattere ‘%’ e la specifica di conversione possono esserci, nell’ordine da sinistra:
๏ Opzioni di allineamento (\t, \n,…)
๏ L’ampiezza minima del campo
๏ Un punto se si vuole specificare la precisione
๏ La precisione
๏ L’ampiezza minima indica il numero di c a r a t t e r i r i s e r v a t o ( c a m p o ) p e r rappresentare il valore (compresi l’eventuale segno ‘–’ e il punto decimale ‘.’).
stdin
stderr
stdout
Lecture Plan
๏ Funzioni di Input e Output
๏ Strutture selettive ed iterative
Strutture di controllo
๏ In ogni linguaggio le strutture di controllo permettono di scrivere programmi nei quali il flusso di esecuzione non sia strettamente sequenziale.
๏ I costrutti possono essere:
๏ condizionali: if-else, switch
๏ iterativi: while, do … while, for
Istruzione if-else
๏ L’istruzione condizionale if-else viene usata per esprimere una decisione.
La sintassi più generale è:
if (espressione) istruzione_1
else
istruzione_2
๏ if valuta l’espressione, e se risulta vera (non nulla) viene eseguita l’istruzione_1; in caso contrario viene eseguita l’istruzione_2.
Istruzione if-else
Esempio
if (i != 0)
x = a / i;
else
printf (“Divisione impossibile");
Istruzioni if
๏ Nel costrutto if-else la parte relativa all’else è opzionale. L’if semplice permette delle codifiche molto compatte, quando non è necessaria la ramificazione delle istruzioni.
if (k == 0)
printf ("k vale zero\n");
if (x > 0) {
z = y / x;
printf ("z vale %f\n", z);
}
๏ All’interno di un costrutto condizionale si possono eseguire anche dei blocchi di istruzioni
…
test
blocco 1
…
Si No
blocco 2
Istruzioni if annidate
๏ In assenza di un else all’interno di una sequenza di if annidati, ogni else viene associato all’if più vicino
๏ L’indentazione non è discriminante per il compilatore; con gli if annidati, ogni ambiguità va risolta utilizzando le parentesi.
if (n > 0)
if (a > b) z = a;
else
z = b;
if (n > 0) { if (a > b)
z = a;
else
z = b;
}
Istruzioni if annidate
๏ Per fare in modo che il costrutto precedente sia interpretato correttamente dal compilatore, si dovrà scrivere:
if (n > 0) { if (a > b) z = a;
}
else
z = b;
Costrutti iterativi (cicli)
๏ L’iterazione serve a fare in modo che un’istruzione o un blocco di istruzioni vengano eseguite ripetutamente per “un certo numero di volte”
๏ Tale numero può essere:
๏ noto a priori, essendo uguale al valore di una costante o di una variabile che non muta durante l’iterazione
๏ determinato da condizioni dipendenti dall’iterazione
๏ In C esistono tre costrutti iterativi:
๏ while
๏ do … while
๏ for
Ciclo while
๏ Il costrutto while ha la sintassi:
while (espressione) istruzione;
๏ oppure
while (espressione) { blocco di istruzioni }
๏ Se l’espressione risulta vera, allora viene eseguito il blocco di istruzioni, al termine del quale l’espressione viene rivalutata.
๏ Non appena l’espressione diventa falsa, l’iterazione si interrompe e viene eseguita la prima istruzione successiva al costrutto while
…
blocco test istruzioni
… Si
No
Ciclo while
๏ Il frammento di codice
i = 1;
while (i <= 100) {
printf ("Messaggio ripetuto 100 volte\n");
i = i + 1;
}
๏ verifica la condizione i <= 100 e, trovandola vera per i = 1, esegue il ciclo while, stampa il messaggio, incrementa di uno la variabile i, e ripete la verifica della condizione. L’iterazione prosegue fino a quando i raggiunge il valore 101 > 100.
Ciclo do … while
๏ La sintassi del costrutto do … while è la seguente:
do
istruzione;
while (espressione);
๏ oppure:
do {
blocco di istruzioni } while (espressione);
๏ L’istruzione (o il blocco di istruzioni) viene sempre eseguita almeno una volta; al termine viene valutata l’espressione e, finché questa è vera, l’istruzione viene ripetuta e l’espressione rivalutata (iterazione), altrimenti si passa all’istruzione successiva.
Si
No test
…
blocco istruzioni
…
Ciclo for
๏ Il costrutto for ha la sintassi:
for (espr_1; espr_2; espr_3) istruzione;
๏ oppure
for (espr_1; espr_2; espr_3) { blocco di istruzioni
}
๏ espr_1 rappresenta un’istruzione di inizializzazione
๏ espr_2 è la condizione da verificare prima di ogni iterazione
๏ e s p r _ 3 r a p p r e s e n t a u n ’ i s t r u z i o n e d i aggiornamento, eseguite ad ogni ciclo dopo le istruzioni.
…
blocco test istruzioni
… Si
No
Ciclo for
๏ Il frammento di codice relativo al ciclo while
i = 1;
while (i <= 100) {
printf ("Messaggio ripetuto 100 volte\n");
i = i + 1;
}
๏ può essere riscritto nella forma più semplice:
for (i = 1; i <= 100; i++)
printf ("Messaggio ripetuto 100 volte\n");