corso di laboratorio di linguaggi - alucente/didattica/lnga1.pdf · – 3 serie di esercizi di...

30
1 Corso di Laboratorio di Linguaggi - A Il linguaggio C Docente Maurizio Lucenteforte Informazioni sul corso Docente: Dott. Maurizio Lucenteforte Tel. 011/6706774 (Lab.) 011/6706753 (Studio) Email: [email protected] Orario di ricevimento: Giovedì, ore 15:30/17:30, studio n.54 oppure Lab.di Segnali e Immagini

Upload: hanhan

Post on 18-Feb-2019

217 views

Category:

Documents


0 download

TRANSCRIPT

1

Corso di Laboratorio di Linguaggi - A

Il linguaggio C

DocenteMaurizio Lucenteforte

Informazioni sul corso

• Docente:Dott. Maurizio LucenteforteTel. 011/6706774 (Lab.) 011/6706753 (Studio)Email: [email protected]

• Orario di ricevimento:Giovedì, ore 15:30/17:30, studio n.54 oppureLab.di Segnali e Immagini

2

Informazioni sul corso• Testi di consultazione del corso:

– Linguaggio C. Brian W. Kernighan, Dennis M.Ritchie. Jackson Libri, Prentice Hall SoftwareSeries

– C, corso completo di programmazione. Harvey M.Deitel, Paul J. Deitel, Apogeo

• Orario di ricevimento: Giovedì, ore15:30/17:30, studio n.54 oppure Lab.diSegnali e Immagini

Informazioni sul corso• Orario del corso:

- Lunedì, ore 9-11- Giovedì, ore 9-11- Venerdì, ore 11-13

• Indirizzo WEB del sito: seguire il link dal sito delladidattica (laboratorio di linguaggi A) oppure

http://www.di.unito.it/~lucente/didattica/LngA.html

• Modalità di svolgimento del corso e dell’esame:– 3 serie di esercizi di programmazione in C, da svolgere in gruppo e

da consegnare entro date da stabilire.– prova scritta, il cui primo appello avrà luogo dopo la fine del corso.

3

Informazioni sul corso• Modalità di svolgimento del corso e dell’esame:

– la formazione dei gruppi (normalmente 2 persone) avvienecompilando una form, che sarà presto disponibile sul sito del corso.Conferma della ricezione del modulo contenente il numeroassegnato al gruppo sarà inviata per e-mail agli interessati.

– i testi degli esercizi e le date di scadenza saranno resi notiattraverso la pagina web del corso.

– chi non fosse in grado di rispettare le scadenze non potràaggregarsi a gruppi esistenti né formarne di nuovi, ma dovràsvolgere individualmente, oltre a quelli suddetti, degli eserciziintegrativi il cui testo sarà pubblicato sul sito del corso.

– Le consegne avvengono elettronicamente, compilando una formche sarà presto disponibile sul sito del corso.

– Per poter sostenere l'esame scritto occorre aver consegnato gliesercizi richiesti.

Programma del corso• Ambiente di sviluppo: compilatori utilizzabili.• Introduzione al Linguaggio C: storia e

caratteristiche del linguaggio, fasi diesecuzione, struttura di un programma,preprocessore.

• Costanti, variabili: dichiarazioni e tipi,istruzioni di assegnamento, classi dimemorizzazione, espressioni, operatori,casting.

• Librerie standard di funzioni, definizione difunzioni, ricorsione.

4

Programma del corso• Espressioni condizionali, istruzioni di

selezione (if, if/else), cicli (while, do/while, for)• Strutture, vettori, vettori come parametri di

funzioni, stringhe• Puntatori, allocazione dinamica della

memoria, operazioni ed aritmetica deipuntatori.

• Operazioni di I/O.

Ambiente di sviluppo• Durante lo svolgimento del corso verranno

svolti nei laboratori degli esercizi di C alcalcolatore. Nei laboratori è installatol’ambiente di sviluppo Borland Turbo C++ 3.0,funzionante in modalità DOS, dotato di editor,compilatore, linker, debugger.

• Per esercitarvi a casa potete utilizzare unqualunque compilatore C.

• Potete trovare una lista di compilatoriscaricabili via web gratuitamente(es. DEV-C++, LCC-Win32) all’indirizzo:http://www.bloodshed.net/compilers

5

La storia linguaggio C• Tappe storiche nella definizione del C:

- Evolve da due precedenti linguaggi diprogrammazione, BCPL e B- E’ stato utilizzato per sviluppare il sistemaoperativo UNIX, viene comunemente usato perscrivere SO- Indipendente dall’hardware (portabile)

• Standardizzazione- inizialmente sono state definite molte piccolevarianti del C, incompatibili tra loro- ANSI (American National Standards Institute) siè occupato della sua standardizzazione, nel1989, standard aggiornato nel 1999

Caratteristiche del linguaggio

• Linguaggio a medio/alto livello, ma senzagerarchie di funzioni. Basso livello di controllodegli errori nella fase di compilazione.

• Linguaggio tipato, ma permette notevolipossibilità di conversione mediante lacoercizione (type casting), e cioe' permette diforzare una variabile di un tipo ad essere unavariabile di un altro tipo utilizzando l'operatore"()".

• Abbina ad un medio-alto livello di astrazioneanche un buon controllo delle operazioni abasso livello.

6

Fasi per l’esecuzione di unprogramma C

• Preprocessing: il preprocessore si occupa diincludere altri file e sostituisce simboli specialiche seguono particolari direttive.

• Compilazione: traduce il programma in codiceoggetto (linguaggio macchina).

• Linking: risolve riferimenti a funzioni e variabilidefinite altrove (es. in librerie standard o definitedall’utente), producendo una immagineeseguibile

• Loading: carica in memoria il codice eseguibile

• Esecuzione

Esempio di programma C/* Calcola la media dei voti di una classe */

#include <stdio.h>

int main(void){ int counter, voto, totale, media;

/* inizializzazioni */

totale = 0; counter = 1;

/* inserimento ed elaborazione dei voti */ while ( counter <= 10 ) { printf( ”Inserisci il voto: " ); scanf ( "%d", &voto );

totale = totale + voto; counter = counter + 1; }

/* calcolo e output del risultato */ media = totale / 10;

printf( ”La media della classe è %d\n", media ); return 0; /* Indica che il programma è terminato senza errori */

}

7

Parole chiave

Keywordsauto double int structbreak else long switchcase enum register typedefchar extern return unionconst float short unsignedcontinue for signed voiddefault goto sizeof volatiledo if static while

Osservazioni• Il set di istruzioni del C è molto limitato: le

primitive più comunemente utilizzate (es. I/O,matematiche) sono contenute nelle libreriestandard del C sotto forma di funzioni. Seutilizzo delle funzioni contenute in una certalibreria, questa deve essere inclusa mediante ladirettiva #include del preprocessore.

• In questo caso, dal momento che la funzione dioutput printf() è contenuta della libreria standardstdio.h, deve essere presente la direttiva diinclusione: #include <stdio.h>

8

Osservazioni• In generale # è il simbolo con cui iniziano i

comandi del preprocessore. Tali comandi nonsono terminati da ;

• I commenti sono inseriti tra i caratteri /* e */ evengono ignorati in fase di compilazione.

• Ogni programma comincia la sua esecuzionecon la funzione main.

• In int main (void), la sintassi indica che ilprogramma non ha argomenti di ingresso e cherestituisce un valore intero (che indica laterminazione con successo).

Il preprocessoreAzioni:

• Definizione delle costanti simboliche e dellemacro.

• Compilazione condizionale del codice.

• Esecuzione condizionale delle direttive delpreprocessore.

9

Il preprocessore• La direttiva #include: consente di includere in

sua vece la copia di un file specificato. Esistonodue forme:

#include <nome_file>#include “nome_file”

la prima viene utilizzata per includere file diintestazione della libreria standard, che sonomemorizzati in directory standard (dipendentidall’implementazione del compilatore), mentre laseconda è utilizzata per includere file diintestazione definiti dal programmatore.

Il preprocessore• La direttiva #define: è utilizzata per definire

costanti simboliche e macro. Il formato è:#define identificatore testo_di_sostituzione

in questo modo, all’interno del file in cui è definito,tutte le successive occorrenze dell’identificatoresaranno automaticamente sostituite daltesto_di_sostituzione, prima della compilazione:

Esempio:#define PI 3.14159

sostituirà tutte le occorrenze della costantesimbolica PI con quella numerica 3.14159

10

Il preprocessore• Creazione di macro mediante #define: le macro

possono essere definite con o senza argomenti.

– Una macro senza argomenti viene elaboratacome una costante simbolica.

– In una macro con argomenti, questi sarannorimpiazzati all’interno del testo di sostituzionee solo in seguito sarà espansa la macro: inaltri termini, il testo di sostituzione rimpiazzeràla lista degli identificatori e degli argomentiall’interno del programma.

Il preprocessore• Esempio di applicazione di macro:

#define AREA_CERCHIO(x) ( PI * (x) * (x) )In qualsiasi parte del file appaia AREA_CERCHIO(r), ilvalore di c sarà usato al posto di x nel testo disostituzione, la costante PI sarà rimpiazzata dal suovalore (definito precedentemente) e la macro verràespansa all’interno del programma.– Esempio 1: il comando area = AREA_CERCHIO(4);

sarà espanso in area = ( 3.14159 * (4) * (4) );

– Esempio 2: il comando area = AREA_CERCHIO(c+2);

sarà espanso in area = ( 3.14159 * (c+2) * (c+2) );

11

Il preprocessore• Osservazione: la macro AREA_CERCHIO potrebbe

essere definita anche come funzione:

double areaCerchio(double x)

{ return 3.14159 * x * x;

}

• In questo caso i vantaggi nell’uso delle macro sonodovuti al risparmio nella definizione di una funzione e nelmiglioramento nella leggibilità del programma.

• Esempio con più argomenti#define AREA_RECTANGLE( x, y ) ( ( x ) * ( y ) )l’istruzione:

rectArea = AREA_RETTANGOLO( a + 4, b + 7 );verrà trasformata in

rectArea = ( ( a + 4 ) * ( b + 7 ) );

Il preprocessore• Compilazione condizionale: consente al

programmatore di controllare l’esecuzione delledirettive del preprocessore e la compilazione delcodice del programma. Le direttive condizionalidel preprocessore vengono valutate comeespressioni costanti intere.Esempio:

#define DEBUG 1#ifdef DEBUG

printf(“Variabile x = %d\n”, x );#endif

fa si che l’istruzione printf venga compilata (ed eseguita)solo nel caso in cui la variabile DEBUG sia definita a 1

12

CostantiLa definizione di identificatori per le costanti, altre

che con il comando di preprocessore #define,può avvenire usando il modificatore const:

const tipo nome_costante = valore ;

Esempi:const double e = 2.71828182845905;

const char tm[] = “type mismatch”;

Variabili• Tipi di base

– char: carattere– int: intero– float: virgola mobile, singola precisione– double virgola mobile, doppia precisione– void: tipo di ritorno di una procedura, tipo generico di

puntatore• Modificatori:

– unsigned: (unsigned int)– short: (short int)– long: (long int, long double)

13

Variabili• Sui sistemi UNIX tutte le variabili dichiarate "int" sono

considerate "long int", mentre "short int" deve esseredichiarato esplicitamente.

• Per dichiarare una varibile si scrive:var_tipo elenco-variabili-separate-da-virgole ;

• E' possibile preinizializzare una variabile utilizzando =(operatore di assegnazione).Esempio: int i,j,k=1; float x=2.6,y; char a;

Classi di memorizzazione• Classe di memorizzazione: auto, register, extern, static

• Permanenza in memoria: periodo durante il qualequell’identificatore risiede in memoria

• Visibilità (scope): parti del programma in cui è possibilefare riferimento all’identificatore.

• Collegamento: specifica i file in cui un identificatore èdefinito

• Classe di memorizzazione automatica: è associata alleparole chiave auto, register, gli oggetti sono creati edistrutti ogni qualvolta si entrerà e si uscirà dal blocco incui sono creati.– auto: è il default per le variabili locali

auto double x, y;

14

Classi di memorizzazione– register: il compilatore tenta di inserire tali variabili in

registri di memoria. Può solo essere usato per variabiliautomatiche.

register int counter = 1;• Classe di memorizzazione statica: le variabili esistono

durante l’esecuzione dell’intero programma. Sonoinizializzate per default a zero.– static: variabili locali definite in funzioni.

• Mantengono l’allocazione e il loro valore e dopo laterminazione della funzione in cui sono definite.

• Sono visibili solo all’interno di tale funzione.– extern: estende la visibilità della variabile o della

funzione anche ad altri file del programma,demandando al linker di risolvere il riferimento.

Espressioni e assegnazioniLe espressioni sono definite dalla grammatica:espressione ::= variabile | costante | operatore(lista_espressioni)

• Gli operatori aritmetici binari si scrivono in notazioneinfissa, utilizzando parentesi, secondo le usualiconvenzioni di precedenza. Ad esempio:x + 25 * (y - 1) + x % y

• Le assegnazioni hanno la forma:variabile = espressione ;

• Un' assegnazione in C è un'espressione, il cui valore è ilvalore assegnato alla variabile a sinistra del simbolo `=´

• Osservazioni:– E’ possibile fare assegnazioni all’interno di espressioni, es:

if ((n = strlen(s)) > 10)

– E’ possibile fare assegnazioni multiple simultanee, es:x = y = z = 0;

15

Operatori aritmetici• Come già accennato, le assegnazioni in C

vengono effettuate utilizzando "=". Oltre aglioperatori aritmetici standard +, -, *, / eall'operatore % (modulo) per gli interi, in C sihanno anche gli operatori incremento ++ edecremento --, che possono essere preposti oposposti all'argomento. Se sono preposti il valoree' calcolato prima che l'espressione sia valutata,mentre se sono posposti il valore viene calcolatodopo la valutazione della espressione. Esempi:

int x,z = 2; x=(++z)-1; /* A questo punto x=2 e z=3 */

int x,z = 2; x=(z++)-1; /* A questo punto x=1 e z=3 */

Operatori aritmetici• L'operatore "%" (modulo) può essere utilizzato solamente

con le variabili di tipo integer; la divisione "/" e' utilizzatasia per gli integer che per i float.

• Esiste una forma contratta per espressioni del tipoexpr1 = expr1 op expr2 ad esempio: i=i+2 o x=x*(y+3))

che diventano:expr1 op = expr2

• In particolare:– x+=y; equivale a x=x+y;

– x-=y; equivale a x=x-y;

– x*=y; equivale a x=x*y;

– x/=y; equivale a x=x/y;

• Osservazione: l'espressione x*=y+3 corrisponde ax=x*(y+3) e non a x=x*y+3.

16

Operatori di confronto• x==y Testa se il valore di x è uguale a y• x>y Testa se x è maggiore di y

• x>=y Testa se x è maggiore uguale di y

• x<y Testa se x è minore di y

• x<=y Testa se x è minore uguale di y

• Osservazione: if (i==j) ... esegue il contenuto dell'if se ie' uguale a j, ma if (i=j) ... e' ancora sintatticamenteesatto ma effettua l'assegnazione del valore di j ad i eprocede se j e' diverso da zero in quanto vieneinterpretato il valore TRUE (e' come scrivere if (i)... con idiverso da zero). In questo caso si tratta di una"assegnazione di valore”, come visto in precedenza.

Operatori logici e bitwise• Operatori logici:

– "&&”: AND logico– "||”: OR logico– "!”: NOT.

• Operatori bitwise, operano sui singoli bit delle variabili:– "&”: AND "|”: OR "^”: XOR– "~”: complemento a 1 (0=>1, 1=>0)

– "<<”: shift a sinistra ">>”: shift a destra

• Esempio: z<<2 shifta i bit in z di due posti verso sinistracosi', se z=00000010 (binario) o 2 (decimale)allora, z>>=2 => z=00000000 (binario) o 0 (decimale)inoltre, z<<=2 => z=00001000 (binario) o 8 (decimale)

• Osservazione: uno shift a sinistra e' equivalente ad unamoltiplicazione per 2, mentre uno shift a destra equivalead una divisione per 2.

17

Espressioni booleane• Il C non prevede il tipo “booleano”. Al loro posto si usano

gli interi:– 0 (false) qualunque intero > 0 (true)

• generalmente è preferibile definire le costanti:– #define TRUE 1 oppure const int true = 1;– #define FALSE 0 oppure const int false = 0;

• Le espressioni booleane si formano utilizzando:• Simboli relazionali: > >= < <=• Simboli di eguaglianza e diseguaglianza: == !=• Connettivi: && (and) || (or) ! (not)

Esempi:( (x > 3) && ((y == 1) || !(y > 0) ) )

Regole di precedenza degli operatori• E' necessario fare attenzione al significato di

un'espressione come a + b * c dove potremmovolere sia l'effetto di (a + b) * c sia quello dia +(b * c)

• Tutti gli operatori hanno una propria priorità, e glioperatori ad alta priorità sono valutati prima diquelli a bassa priorità.

• Gli operatori con la stessa priorità sono valutatida sinistra a destra. Ad esempio:a - b - c e' valutato (a - b) - c

18

Regole di precedenza degli operatori Priorità dalla più alta alla più bassa: () [] -> . ! ~ - * & sizeof cast ++ -- (right -> left) * / % + - < <= >= >

== != & ^ | && ||

? : (right -> left) = += -= (right -> left) ,(comma)

Esempioa < 10 && 2 * b < c

e' interpretato come:"(a < 10) &&((2 * b) < c)".

Conversioni di tipo (casting)• Il C fornisce l’operatore unario cast (operatore di

conversione).• Conversione esplicita:

Esempio:float media;int totale, contatore;media = (float) totale / contatore ;

l’operatore unario (float) ha la funzione di creare unacopia temporanea in virgola mobile di total, realizzandouna conversione esplicita, in modo da avere comerisultato dell’operazione di divisione ancora un valore invirgola mobile. Senza l’utilizzo dell’operatore di cast ilrisultato sarebbe stato l’assegnamento a media delladivisione intera tra totale e contatore.

19

Conversioni di tipo (casting)• Conversione implicita: il compilatore C sa solo valutare

espressioni tra argomenti dello stesso tipo. Perassicurare questo, effettuerà una operazione dipromozione (o conversione implicita) di tutti i dati al tipo‘più alto’ contenuto nell’espressione (ad esempiogenererà una copia degli operandi interi promuovendoli afloat, nel caso in cui sia presente nell’espressione unoperando float).

• Una sorta di conversione implicita (detta coercizione)viene adottata anche nel caso di passaggio di parametridi funzioni, in questo caso senza rispettare le regole dipromozione delle variabili, ma tenendo conto dei tipi deiparametri formali definiti nei prototipi delle funzioni stesse,come sarà visto in dettaglio più avanti.

Struttura di un programma C/* commenti: nome programma, descrizione, etc. */

istruzioni per il preprocessore

dichiarazione di tipi, variabili, costanti

tipo_di_ritorno main (lista_argomenti){

dichiarazione variabili locali

sequenza di istruzioni

}

tipo_di_ritorno funzione_1 (lista_argomenti){

dichiarazione variabili localisequenza di istruzioni

}

tipo_di_ritorno funzione_n (lista_argomenti){ … }

Programma principalemain

blocco

Inizio blocco

fine blocco

sottoprogrammi

20

Funzioni• Si vogliono costruire programmi formati da

componenti piccole e semplici• Queste componenti vengono dette moduli• Ogni modulo è più facilmente gestibile/utilizzabile• I moduli in C sono rappresentati dalle funzioni• I programmi in C combinano funzioni definite dal

programmatore con funzioni di libreria standard• La libreria standard del C ha una vasta varietà di

funzioni

Struttura di una funzione

tipo_di_ritorno nome_funzione (lista_argomenti)

{

dichiarazioni

sequenza di istruzioni

}

la lista_argomenti ha la forma:tipo1 var1, …… , tipon varn

21

Funzioni: parametri e valori di ritorno• Il C fornisce delle funzioni anch'esse simili alla maggior

parte degli altri linguaggi. Una differenza e' che il Cconsidera "main()" come una funzione. A differenza dialcuni linguaggi, come il Pascal, il C non ha procedurepoiché usa le funzioni per soddisfare entrambe leesigenze.

• Le funzioni possono ritornare un valore (possono essereutilizzate nelle espressioni):return espressione ;

• Se non si vuole ritornare alcun valore da una funzione e'sufficiente dichiararla di tipo void ed omettere il return.

• Nota: e' obbligatorio mettere le parentesi () dopo il nomedella funzione anche se non ci sono parametri, adifferenza di altri linguaggi.

Funzioni: parametri e valori di ritorno• I parametri in C sono sempre passati per valore.• Il passaggio per riferimento si simula passando

esplicitamente l'indirizzo del parametro attuale: quindi ilparametro formale sarà di tipo puntatore.

• Non è possibile passare/ritornare parametri di tipo nonelementare se non attraverso puntatori (con l'eccezione,per l'ANSI-C, delle strutture).

• Il valore della funzione viene ritornato attraversol'istruzione return, la cui esecuzione termina, comunque,l'esecuzione del corpo della funzione. In alternatival’esecuzione termina al raggiungimento di ‘}’

• In C non esiste distinzione tra funzioni e procedure:semplicemente le seconde non contengono l'istruzionereturn; in tal caso (ANSI-C) il tipo di ritorno della funzioneè void.

22

Funzioni: definizione di prototipi• Una definizione di prototipo è costituita da:

– Nome funzione– Lista parametri– Tipo restituito (default int)

• Viene utilizzato per validare l’uso delle funzioni• Permette l’uso della funzione prima della sua definizione

all’interno del programma• Esempio: la funzione definita dal seguente prototipo:

int maximum( int, int, int );

• riceve 3 interi• restituisce un intero

Funzioni: ricorsione• Le funzioni possono richiamare se stesse• Il C permette definizioni ricorsive implicite

Esempio:long fibonacci( long n ){if (n == 0 || n == 1)

return n;else

return fibonacci(n - 1) + fibonacci(n – 2);}

23

Funzioni: ricorsione• Schema delle chiamate ricorsive per n=3:

f( 3 )

f( 1 )f( 2 )

f( 1 ) f( 0 ) return 1

return 1 return 0

return +

+return

Scrittura di un programma su più file• Normalmente un programma C si articola in diversi file, i

quali concorrono alla formazione del codice di un unicoprogramma in due modi:

– Per inclusione in fase di preprocessing.– Nella fase di linking.

• Per favorire la compilazione separata è opportunosuddividere ciascun modulo in due file:

myfile_header .h myfile_code.c

• In myfile_header.h saranno contenute le dichiarazioni ditipi, variabili e funzioni che si desidera siano visibili aglialtri moduli (ed al modulo che contiene il main)

• In myfile_code.c vi sarà il codice delle funzioni pubblichee le dichiarazioni e il codice di tipi, variabili e funzioniprivate, ossia conosciute solo all’interno del modulo.

24

Scrittura di un programma su più file• Quando si scrivono grossi programmi e' consigliabile

suddividere i programmi in moduli, che dovrebberoessere in file sorgenti separati. L'istruzione main() sarà inun solo file (esempio main.c).

• E' possibile creare una propria libreria di funzioniscrivendo un gruppo di subroutine in uno o più moduli.Infatti i moduli possono essere condivisi da diversiprogrammi semplicemente includendoli in fase dicompilazione, come vedremo.

• Ci sono molti vantaggi legati a questo modo di operare:– I moduli verranno naturalmente divisi in gruppi comuni di

funzioni;– E' possibile compilare ogni modulo separatamente e linkarlo

poi nei moduli compilati (come vedremo più avanti);– Vengono accelerate le operazioni di ricompilazione:– Utility come make facilitano la gestione di grossi progetti;

Scrittura di un programma su più file• Se adottiamo un approccio modulare, allora risulterà

spontaneo mantenere all'interno di ogni modulo ladefinizione delle variabili, i prototipi di funzioni, etc.

• Problema: nel caso in cui più moduli necessitino lacondivisione di tali definizioni.

• Soluzione: è consigliabile centralizzare la definizione inun “header file” e condividerlo poi con gli altri moduli.

• E' importante notare che il file header solitamentecontengono solo definizioni di tipi di dati, prototipi difunzioni e comandi per il preprocessore C.

• Avendo diversi moduli, ognuno di essi verra' compilatoseparatamente. Ad esempio, alcuni moduli potrannoincludere un file "header.h” per accedere alle definizionicomuni.

25

Scrittura di un programma su più file• Notiamo che in generale e' necessario decidere tra il

desiderio che ogni modulo ".c" possa accedere alleinformazioni di cui necessita unicamente per il propriolavoro, e la realtà pratica di mantenere molti file header.

• Per i programmi di moderate dimensioni, probabilmentee' meglio mantenere uno o due file header checondividano le definizioni di più di un modulo.

• L’uso di file di header comuni risolve efficientementeanche il problema in merito all'approccio modulareriguardante le variabili di sharing: se abbiamo dellevariabili globali dichiarate ed utilizzate nel modulocorrente, e' possibile fare riconoscere tali variabili aglialtri moduli definendole in un opportuno file di header daincludere in tali moduli.

Costrutto di selezione if• Usata per scegliere tra percorsi di azione

alternativi. Esempio in pseudocodice:Se il voto dello studente è maggiore o uguale a 18

visualizza “promosso”

• In C: if ( voto >= 18 ) printf( "Promosso\n" );

• Struttura con ingresso ed uscita singoli

true

false

voto >= 18 print “Promosso”

26

Costrutto di selezione if/else• if

Esegue un’azione solo se la condizione è vera• if/else

Specifica ed esegue un’azione sia nel caso in cui lacondizione sia vera, sia nel caso in cui sia falsa

• Pseudocodice:Se il voto dello studente è maggiore o uguale a 18

visualizza “promosso”

altrimenti

visualizza “bocciato”

• In C: if ( voto >= 18 )

printf( ”promosso\n");else

printf( ”bocciato\n");

Costrutto di selezione if/else• In C esiste anche l’operatore condizionale di selezione

(?:) ternario:• Ha tre argomenti (condizione, valore se vero,

valore se falso).• Esempio in C:

printf( "%s\n", voto >= 18 ? ”promosso" : ”bocciato" );

oppure voto >= 18? printf( “promosso\n” ) : printf( “bocciato\n” );

truefalse

print “bocciato” print “promosso”

voto >= 18

27

Costrutto di ripetizione while• Specifica un’azione da ripetere fino a quando una

condizione rimane vera.• Pseudocodice:

finchè esistono elementi nella mia lista della spesa compra il prossimo elemento e cancellalo dalla lista

• Esempio: int valore = 2;while ( valore <= 1000 )valore = 2 * valore;

valore <= 1000 valore = 2 * valoretrue

false

Costrutto di ripetizione do/while• Simile al costrutto while• La condizione di ripetizione viene testata solo dopo

l’esecuzione del blocco di azioni associato.– Il blocco di azioni viene eseguito almeno una volta

• Formato:do { statement;} while ( condition );

• Esempio:counter = 1):do {

printf( "%d ", counter );} while (++counter <= 10);

28

Costrutto di ripetizione do/while• Diagramma di flusso:

true

false

action(s)

condition

Costrutto di ripetizione for• Permette di gestire direttamente nella sintassi del ciclo

una fase di inizializzazione e di aggiornamento di variabili• Formato:

for ( initialization; loopContinuationTest; update )

• Esempio: for( int contatore = 1; contatore <= 10; contatore++ )

printf( "%d\ n ", contatore );

• Il costrutto di ripetizione for è equivalente ad un ciclogestito tramite while:

initialization;while ( loopContinuationTest ) { statement; update;}

29

Costrutto di ripetizione for• Note sui comandi di inizializzazione e aggiornamento:

– Possono essere liste di comandi separati da virgola– Esempio:

for (int i = 0, j = 0; j + i <= 10; j++, i++) printf( "%d\n", j + i );

• Inizializzazione, test e aggiornamento possono contenereespressioni aritmetiche. Esempio:

for ( j = x; j <= 4 * x * y; j += y / x )• Se il test di terminazione è inizialmente falso:

– Il blocco del costrutto for non viene eseguito– Il controllo passa all’istruzione successiva al blocco

del for

Costrutto di selezione multipla switch• Utile quando una variabile o una espressione deve

essere testata per tutti i valori al fine di eseguire diverseazioni.

• Formato: una serie di etichette case e una etichettaopzionale default.

switch ( value ){case '1':

actionscase '2':

actionsdefault:

actions}

• break: utilizzato per uscire dal costrutto.

30

Costrutto di selezione multipla switch• Diagramma di flusso:

true

false

.

.

.

case a case a action(s) break

case b case b action(s) break

false

false

case z case z action(s) break

true

true

default action(s)

Comandi break e continue• break:

– Causa l’uscita immediata da un while, for, do/while oswitch

– L’esecuzione continua con la prima istruzioneseguente al blocco che contiene il comando break

• continue:– Salta le istruzioni restanti all’interno del blocco di un

while, for, do/while.– Procede alla prossima iterazione del ciclo– while e do/while: il test di continuazione viene

valutato immediatamente dopo l’esecuzione dicontinue.

– For: viene valutata l’espressione di aggiornamento,quindi viene valutato il test di continuazione.