Corso di Laurea in Informatica e Tecnologie per la Produzione del Sofware (Track B) - A.A. 2016/2017 Laboratorio di Informatica Linguaggio C (Parte 1) docente: Cataldo Musto cataldo.musto@uniba.it
Linguaggio C Perchè il linguaggio C? C è piccolo (numero limitato di istruzioni) Abbastanza semplice da imparare E efficiente Caratterizzato da un buon livello di portabilità 10/03/2017 2
Linguaggio C C Evoluzione di due precedenti linguaggi di programmazione, BCPL e B (by Ritchie) Usato per scrivere i moderni sistemi operativi Il sistema operativo UNIX è scritto in C Standardizzazione Inizialmente esistevano diverse varianti del C, ma non erano compatibili tra di loro. E stato formato un comitato per creare una definizione non ambigua, e machine-independent" Standard creato nel 1989, aggiornato nel 1999 (la versione più comune, detta C-99) riaggiornato nel 2011 10/03/2017 3
Recap: compilazione codice sorgente Editor Preprocessor Compiler Linker Loader 10/03/2017 4
Recap: compilazione codice sorgente Editor Preprocessor Compiler Linker Loader Scrittura del codice sorgente (in un IDE o con un semplice file di testo) 10/03/2017 5
Recap: compilazione codice sorgente Editor Preprocessor Compiler Linker Loader Risoluzione delle direttive, ad esempio #define (utilizzata per definire costanti, ad esempio) e #include (utilizzata per includere codice scritto in librerie esterne) 10/03/2017 6
Recap: compilazione codice sorgente Editor Preprocessor Compiler Linker Loader Verifica la correttezza sintattica del codice sorgente e costruisce un file oggetto (con estensione.o) che viene salvato su disco. Errori logici (reversibili o irreversibili) non vengono individuati dal compilatore. 10/03/2017 7
Recap: compilazione codice sorgente Editor Preprocessor Compiler Linker Loader Collega i vari file oggetto costruiti dal compilatore e unisce eventuali librerie esterne, al fine di generare il file eseguibile 10/03/2017 8
Recap: compilazione codice sorgente Editor Preprocessor Compiler Linker Loader Carica in memoria e lancia l eseguibile compilato. Il processo è preso in carico dalla CPU che esegue sequenzialmente le istruzioni ed eventualmente alloca della memoria per creare variabili, file su disco, etc. 10/03/2017 9
Linguaggio C: il primo programma 1 /* Fig. 2.5: fig02_05.c 2 Addition program */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 int integer1; /* first number to be input by user */ 9 int integer2; /* second number to be input by user */ 10 int sum; /* variable in which sum will be stored */ 11 12 printf( "Enter first integer\n" ); /* prompt */ 13 scanf( "%d", &integer1 ); /* read an integer */ 14 15 printf( "Enter second integer\n" ); /* prompt */ 16 scanf( "%d", &integer2 ); /* read an integer */ 17 18 sum = integer1 + integer2; /* assign total to sum */ 19 20 printf( "Sum is %d\n", sum ); /* print sum */ 21 22 return 0; /* indicate that program ended successfully */ 23 24 } /* end function main */ 10/03/2017 10
Linguaggio C: il primo programma 1 /* Fig. 2.5: fig02_05.c 2 Addition program */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 int integer1; /* first number to be input by user */ 9 int integer2; /* second number to be input by user */ 10 int sum; /* variable in which sum will be stored */ 11 12 printf( "Enter first integer\n" ); /* prompt */ 13 scanf( "%d", &integer1 ); /* read an integer */ 14 15 printf( "Enter second integer\n" ); /* prompt */ 16 scanf( "%d", &integer2 ); /* read an integer */ 17 18 sum = integer1 + integer2; /* assign total to sum */ 19 20 printf( "Sum is %d\n", sum ); /* print sum */ 21 22 return 0; /* indicate that program ended successfully */ 23 24 } /* end function main */ Riga 3: direttive al preprocessore. Aggiunge le funzioni per gestire i flussi di input/output 10/03/2017 11
Linguaggio C: il primo programma 1 /* Fig. 2.5: fig02_05.c 2 Addition program */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 int integer1; /* first number to be input by user */ 9 int integer2; /* second number to be input by user */ 10 int sum; /* variable in which sum will be stored */ 11 12 printf( "Enter first integer\n" ); /* prompt */ 13 scanf( "%d", &integer1 ); /* read an integer */ 14 15 printf( "Enter second integer\n" ); /* prompt */ 16 scanf( "%d", &integer2 ); /* read an integer */ 17 18 sum = integer1 + integer2; /* assign total to sum */ 19 20 printf( "Sum is %d\n", sum ); /* print sum */ 21 22 return 0; /* indicate that program ended successfully */ 23 24 } /* end function main */ Riga 3: direttive al preprocessore. Aggiunge le funzioni per gestire i flussi di input/output Riga 6: il main è la funzione principale 10/03/2017 12
Linguaggio C: il primo programma 1 /* Fig. 2.5: fig02_05.c 2 Addition program */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 int integer1; /* first number to be input by user */ 9 int integer2; /* second number to be input by user */ 10 int sum; /* variable in which sum will be stored */ 11 12 printf( "Enter first integer\n" ); /* prompt */ 13 scanf( "%d", &integer1 ); /* read an integer */ 14 15 printf( "Enter second integer\n" ); /* prompt */ 16 scanf( "%d", &integer2 ); /* read an integer */ 17 18 sum = integer1 + integer2; /* assign total to sum */ 19 20 printf( "Sum is %d\n", sum ); /* print sum */ 21 22 return 0; /* indicate that program ended successfully */ 23 24 } /* end function main */ Riga 3: direttive al preprocessore. Aggiunge le funzioni per gestire i flussi di input/output Riga 6: il main è la funzione principale Riga 8-10: dichiariamo variabili di tipo intero 10/03/2017 13
Linguaggio C: il primo programma 1 /* Fig. 2.5: fig02_05.c 2 Addition program */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 int integer1; /* first number to be input by user */ 9 int integer2; /* second number to be input by user */ 10 int sum; /* variable in which sum will be stored */ 11 12 printf( "Enter first integer\n" ); /* prompt */ 13 scanf( "%d", &integer1 ); /* read an integer */ 14 15 printf( "Enter second integer\n" ); /* prompt */ 16 scanf( "%d", &integer2 ); /* read an integer */ 17 18 sum = integer1 + integer2; /* assign total to sum */ 19 20 printf( "Sum is %d\n", sum ); /* print sum */ 21 22 return 0; /* indicate that program ended successfully */ 23 24 } /* end function main */ Riga 3: direttive al preprocessore. Aggiunge le funzioni per gestire i flussi di input/output Riga 6: il main è la funzione principale Riga 8-10: dichiariamo variabili di tipo intero Riga 12-13: stampa di una stringa, lettura di un valore e memorizzazione in una variabile. Ricordiamo che una variabile è un nome che identifica una locazione di memoria, quindi serve l operatore & per referenziare l indirizzo di quella variabile 10/03/2017 14
Linguaggio C: il primo programma 1 /* Fig. 2.5: fig02_05.c 2 Addition program */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 int integer1; /* first number to be input by user */ 9 int integer2; /* second number to be input by user */ 10 int sum; /* variable in which sum will be stored */ 11 12 printf( "Enter first integer\n" ); /* prompt */ 13 scanf( "%d", &integer1 ); /* read an integer */ 14 15 printf( "Enter second integer\n" ); /* prompt */ 16 scanf( "%d", &integer2 ); /* read an integer */ 17 18 sum = integer1 + integer2; /* assign total to sum */ 19 20 printf( "Sum is %d\n", sum ); /* print sum */ 21 22 return 0; /* indicate that program ended successfully */ 23 24 } /* end function main */ Riga 3: direttive al preprocessore. Aggiunge le funzioni per gestire i flussi di input/output Riga 6: il main è la funzione principale Riga 8-10: dichiariamo variabili di tipo intero Riga 12-13: stampa di una stringa, lettura di un valore e memorizzazione in una variabile. Ricordiamo che una variabile è un nome che identifica una locazione di memoria, quindi serve l operatore & per referenziare l indirizzo di quella variabile 10/03/2017 15
Linguaggio C: il primo programma 1 /* Fig. 2.5: fig02_05.c 2 Addition program */ 3 #include <stdio.h> 4 5 /* function main begins program execution */ 6 int main() 7 { 8 int integer1; /* first number to be input by user */ 9 int integer2; /* second number to be input by user */ 10 int sum; /* variable in which sum will be stored */ 11 12 printf( "Enter first integer\n" ); /* prompt */ 13 scanf( "%d", &integer1 ); /* read an integer */ 14 15 printf( "Enter second integer\n" ); /* prompt */ 16 scanf( "%d", &integer2 ); /* read an integer */ 17 18 sum = integer1 + integer2; /* assign total to sum */ 19 20 printf( "Sum is %d\n", sum ); /* print sum */ 21 22 return 0; /* indicate that program ended successfully */ 23 24 } /* end function main */ Riga 3: direttive al preprocessore. Aggiunge le funzioni per gestire i flussi di input/output Riga 6: il main è la funzione principale Riga 8-10: dichiariamo variabili di tipo intero Riga 12-13: stampa di una stringa, lettura di un valore e memorizzazione in una variabile. Ricordiamo che una variabile è un nome che identifica una locazione di memoria, quindi serve l operatore & per referenziare l indirizzo di quella variabile Riga 18-20: somma aritmetica, assegnazione di un valore a a una nuova variabile e stampa del valore. Lo specificatore di conversione %d serve a indicare che la variabile è di tipo intero. 10/03/2017 16
Linguaggio C: cenni sulla memoria integer1 45 integer1 45 Ogni variabile è identificata attraverso tre elementi. Quali? integer2 72 integer2 72 sum 117 10/03/2017 17
Linguaggio C: cenni sulla memoria integer1 45 integer2 72 integer1 45 integer2 72 Ogni variabile è identificata attraverso tre elementi. Quali? Nome Tipo Valore Quando dichiariamo una variabile è importante inizializzarla. Perché? Nome Tipo-Valore sum 117 10/03/2017 18
Linguaggio C: cenni sulla memoria integer1 45 integer2 72 Nome Tipo-Valore integer1 45 integer2 72 sum 117 Ogni variabile è identificata attraverso tre elementi. Quali? Nome Tipo Valore Quando dichiariamo una variabile è importante inizializzarla. Perché? Per sovrascrivere il precedente valore memorizzato in quella locazione di memoria 10/03/2017 19
Linguaggio C: cenni sulla memoria integer1 45 integer2 72 Nome Tipo-Valore integer1 45 integer2 72 sum 117 Ogni variabile è identificata attraverso tre elementi. Quali? Nome Tipo Valore Quando dichiariamo una variabile è importante inizializzarla. Perché? Per sovrascrivere il precedente valore memorizzato in quella locazione di memoria Quando assegniamo un valore bisogna usare l operatore &, per indicare di memorizzare il valore nella locazione di memoria cui punta la variabile. 10/03/2017 20
Linguaggio C: cenni sulla memoria integer1 45 integer2 72 Nome Tipo-Valore Il tipo di dato determina il range e la tipologia di valori che una variabile può assumere La scelta del tipo di dato più corretto per una variabile è una importante scelta progettuale in fase di risoluzione del problema e codifica dell algoritmo Ad esempio le variabili di tipo int possono assumere valori tra -32768 e 32767 (65536 valori in tutto) Perchè esattamente 65536? 10/03/2017 21
Linguaggio C: tipi di dato Tipo di dato Dimensione (bits) bit 1 char 8 unsigned char 8 short 16 unsigned short 16 int 16 unsigned int 16 short long 24 unsigned short long 24 long 32 unsigned long 32 float 24 double 24/32 Perché le variabili intere occupano 16 bit, quindi possono assumere 2 16 diverse combinazioni La scelta del tipo di dato da associare a una variabile deve essere operata valutando il dominio della variabile (l insieme dei valori che può assumere). Variabili più piccole riducono la quantità di memoria richiesta dal programma, ma bisogna assicurarsi che i valori da memorizzare nella variabile siano adeguati al tipo di dato scelto. 10/03/2017 22
10/03/2017 23
Problem Solving Prima di scrivere un programma Comprendere a fondo il problema (analisi) Pianificare con cura un approccio per risolverlo (approccio top-down, bottom-up) Produrre una soluzione in pseudo-codice o con I flow-chart Mentre scrivete un programma Individuate quali building blocks sono disponibili (riuso del codice) La maggior parte dei programmi segue una struttura standard Definizione e inizializzazione delle variabili Elaborazione dei dati Visualizzazione in output dei risultati 10/03/2017 24
Problem Solving Prima di scrivere un programma Comprendere a fondo il problema (analisi) Pianificare con cura un approccio per risolverlo (approccio top-down, bottom-up) Produrre una soluzione in pseudo-codice o con I flow-chart Mentre scrivete un programma Individuate quali building blocks sono disponibili (riuso del codice) La maggior parte dei programmi segue una struttura standard Definizione e inizializzazione delle variabili Elaborazione dei dati Visualizzazione in output dei risultati 10/03/2017 25
Programmazione Strutturata Teorema di Bohm e Jacopini: tutti i programmi possono essere scritti usando tre strutture di controllo fondamentali Sequenza: Nativa nel C. I programmi vengono eseguiti sequenzialmente per default Selezione: Il C ne ha tre tipi: if, if else, e switch Iterazione: Il C ne ha tre tipi: while, do while e for 10/03/2017 26
Problema 1.1 Scrivere un programma che stampi un messaggio diverso a seconda che l utente sia maggiorenne o minorenne. Input? Output? Quale tipologia di istruzioni ci serve? 10/03/2017 27
Problema 1.1 Scrivere un programma che stampi un messaggio diverso a seconda che l utente abbia un voto d esame maggiore o minore di 18. Input? Voto dell utente, memorizzata in una variabile di tipo intero Output? Messaggio, diverso a seconda che il voto sia maggiore o minore di 18 Quale tipologia di istruzioni ci serve? Perché? Struttura di selezione. Perché il programma sulla base del valore inserito può sviluppare due diverse alternative. 10/03/2017 28
Struttura di Selezione Usata per scegliere tra diverse alternative Istruzione Pseudocodice Traduzione in C if Se il voto dello studente è maggiore di 18 Stampa Promosso if else Se il voto dello studente è maggiore di 18 Stampa Promosso Altrimenti Stampa Bocciato 10/03/2017 29
Struttura di Selezione Usata per scegliere tra diverse alternative Istruzione Pseudocodice Traduzione in C if Se il voto dello studente è maggiore di 18 Stampa Promosso if ( voto >= 18 ) puts( "Promosso\n" ); if else Se il voto dello studente è maggiore di 18 Stampa Promosso Altrimenti Stampa Bocciato if ( voto >= 18 ) { puts( "Promosso\n" ); } else puts( Bocciato\n" ); Oppure voto >= 60? puts( "Promosso\n" ): puts( Bocciato\n" ); Importante: l indentazione rende il programma più leggibile 10/03/2017 30
Struttura di Selezione Usata per scegliere tra diverse alternative Istruzione Pseudocodice Traduzione in C switch Se il voto dello studente è maggiore di 18 Stampa Promosso Altrimenti Stampa Bocciato Lo pseudocodice è analogo a quella dell istruzione if else ma si esprime in modo diverso. 10/03/2017 31
Struttura di Selezione Usata per scegliere tra diverse alternative Istruzione Pseudocodice Traduzione in C switch Se il voto dello studente è maggiore di 18 Stampa Promosso Altrimenti Stampa Bocciato Lo pseudocodice è analogo a quella dell istruzione if else ma si esprime in modo diverso. switch(eta) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: puts("utente minorenne"); break; default: puts("utente maggiorenne"); } 10/03/2017 32
Struttura di Selezione Usata per scegliere tra diverse alternative Istruzione Pseudocodice Traduzione in C switch Se il voto dello studente è maggiore di 18 Stampa Promosso Altrimenti Stampa Bocciato Lo pseudocodice è analogo a quella dell istruzione if else ma si esprime in modo diverso. switch(eta) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: puts( Promosso\n"); break; default: puts( Bocciato\n"); } E una tipologia di istruzione molto utile se dobbiamo valutare diverse alternative di tipo categorico (non numerico!) es: città di nascita, provincia di residenza, voto di un esame (in lettere, tipo A, B, C ), gruppo sanguigno, etc. 10/03/2017 33
Problema 1.1 Scrivere un programma che stampi un messaggio diverso a seconda che l utente sia maggiorenne o minorenne. if ( voto >= 18 ) { puts( "Promosso\n" ); } else puts( Bocciato\n" ); Aprire una nuova sessione su Repl.it e codificare la soluzione del problema in linguaggio C. Gestire anche eventuali casi limite. 10/03/2017 34
Problema 1.2 Scrivere un programma che conteggi il costo totale dei prodotti in un carrello. Sappiamo che il carrello può contenere esattamente cinque prodotti. Input? Costo dei singoli Output? Messaggio, diverso a seconda che l età sia maggiore o minore di 18 Quale tipologia di istruzioni ci serve? Perché? Struttura di selezione. Perché il programma sulla base del valore inserito può sviluppare due diverse alternative. 10/03/2017 35
Problema 1.2 Scrivere un programma che conteggi il costo totale dei prodotti in un carrello. Sappiamo che il carrello può contenere esattamente cinque prodotti. Input? Costo dei singoli prodotti Output? Costo totale della spesao minore di 18 Quale tipologia di istruzioni ci serve? Perché? Struttura di iterazione. Perché il programma effettua una operazione (ciclica) sommando il costo dei cinque prodotti nel carrello. 10/03/2017 36
Struttura di Iterazione - while Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. condition true action Ripete le istruzioni contenute nel ciclo finchè la condizione è vera. false 10/03/2017 37
Struttura di Iterazione do..while Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. action(s) condition false true Ripete le istruzioni contenute nel ciclo finchè la condizione è vera. Importante: esegue almeno un ciclo! 10/03/2017 38
Struttura di Iterazione for Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. counter = 1 condition true action counter++ Segue la stessa struttura del while, ma utilizza una variabile contatore che viene incrementata dopo il blocco delle istruzioni (action) 10/03/2017 39
Struttura di Iterazione Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while do..while Scrivere un programma che conteggi il costo totale dei prodotti in un carrello. Sappiamo che il carrello può contenere esattamente cinque prodotti. for 10/03/2017 40
Struttura di Iterazione Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while do..while finchè(numero_prodotti<5) leggi costo aggiungi il costo al totale Scrivere un programma che conteggi il costo totale dei prodotti in un carrello. Sappiamo che il carrello può contenere esattamente cinque prodotti. for 10/03/2017 41
Struttura di Iterazione Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while do..while finchè(numero_prodotti<5) leggi costo aggiungi il costo al totale ripeti leggi costo aggiungi il costo al totale finchè(numero prodotti<5) Scrivere un programma che conteggi il costo totale dei prodotti in un carrello. Sappiamo che il carrello può contenere esattamente cinque prodotti. for finchè(numero_prodotti<5) leggi costo aggiungi il costo al totale 10/03/2017 42
Struttura di Iterazione Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while do..while finchè(numero_prodotti<5) leggi costo aggiungi il costo al totale ripeti leggi costo aggiungi il costo al totale finchè(numero prodotti<5) Come lo rendiamo in linguaggio C? for finchè(numero_prodotti<5) leggi costo aggiungi il costo al totale 10/03/2017 43
Struttura di Iterazione Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while do..while finchè(numero_prodotti<5) leggi costo aggiungi il costo al totale ripeti leggi costo aggiungi il costo al totale finchè(numero prodotti<5) while(products<5){ scanf(«%d»,&costo); totale = totale + costo; products++; } do { scanf(«%d»,&costo); totale = totale + costo; products++; } while(products<5); for finchè(numero_prodotti<5) leggi costo aggiungi il costo al totale for(products=0; products<5; products++) { scanf(«%d»,&costo); totale = totale + costo; } 10/03/2017 44
Soluzione (parziale) Scrivere un programma che conteggi il costo totale dei prodotti in un carrello. Sappiamo che il carrello può contenere esattamente cinque prodotti. while(products<5){ scanf(«%d»,&costo); totale = totale + costo; products++; } Soluzione con while Aprire una nuova sessione su Repl.it e codificare la soluzione del problema in linguaggio C. Gestire anche eventuali casi limite (quali?) 10/03/2017 45
Soluzione (con while) 10/03/2017 46
Soluzione (con do while) 10/03/2017 47
Soluzione (con for) 10/03/2017 48
Problema 1.3 Scrivere un programma che conteggio il costo totale dei prodotti in un carrello. Non sappiamo quanti prodotti può contenere il carrello. Input? Costo dei singoli prodotti Output? Costo totale della spesao minore di 18 Quale tipologia di istruzioni ci serve? Perché? Struttura di iterazione. Perché il programma effettua una operazione (ciclica) sommando il costo dei prodotti nel carrello. Non conosciamo a priori il numero di prodotti da inserire. 10/03/2017 49
Problema 1.3 Scrivere un programma che conteggio il costo totale dei prodotti in un carrello. Non sappiamo quanti prodotti può contenere il carrello. Input? Costo dei singoli prodotti Output? Costo totale della spesao minore di 18 Quale tipologia di istruzioni ci serve? Perché? Struttura di iterazione. Perché il programma effettua una operazione (ciclica) sommando il costo dei prodotti nel carrello. Non conosciamo a priori il numero di prodotti da inserire. E necessario introdurre il concetto di iterazione non controllata! 10/03/2017 50
Problema 1.3 Scrivere un programma che conteggio il costo totale dei prodotti in un carrello. Non sappiamo quanti prodotti può contenere il carrello. Input? Costo dei singoli prodotti Output? Costo totale della spesao minore di 18 Quale tipologia di istruzioni ci serve? Perché? Struttura di iterazione. Perché il programma effettua una operazione (ciclica) sommando il costo dei prodotti nel carrello. Non conosciamo a priori il numero di prodotti da inserire. E necessario introdurre il concetto di iterazione non controllata! Non si utilizza un contatore fisso, si utilizza un valore sentinella Se il valore letto è uguale a quel valore, esce dal ciclo. 10/03/2017 51
Struttura di Iterazione (non controllata) Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while Do..while finchè(sentinella=true) leggi costo aggiungi il costo al totale ripeti leggi costo aggiungi il costo al totale finchè(sentinella=true) while(costo!= -1){ scanf(«%d»,&costo); totale = totale + costo; } do { scanf(«%d»,&costo); totale = totale + costo; } while(costo!= -1); for finchè(sentinella=true) leggi costo aggiungi il costo al totale for(costo = 0; costo!= -1;) { scanf(«%d»,&costo); totale = totale + costo; } 10/03/2017 52
Struttura di Iterazione (non controllata) Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while Do..while for finchè(sentinella=true) leggi costo aggiungi il costo al totale ripeti leggi costo aggiungi il costo al totale finchè(sentinella=true) finchè(sentinella=true) leggi costo aggiungi il costo al totale while(costo!= -1){ scanf(«%d»,&costo); totale = totale + costo; } do { scanf(«%d»,&costo); totale = totale + costo; } while(costo!= -1); for(costo = 0; costo!= -1;) { scanf(«%d»,&costo); totale = totale + costo; } Il valore sentinella va nella condizione. Si tendono ad utilizzare valori non validi per quella variabile 10/03/2017 53
Struttura di Iterazione (non controllata) Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while finchè(sentinella=true) leggi costo aggiungi il costo al totale while(costo!= -1){ scanf(«%d»,&costo); totale = totale + costo; } Do..while ripeti leggi costo aggiungi il costo al totale finchè(sentinella=true) do { scanf(«%d»,&costo); totale = totale + costo; } while(costo!= -1); for finchè(sentinella=true) leggi costo aggiungi il costo al totale for(costo = 0; costo!= -1;) { scanf(«%d»,&costo); totale = totale + costo; } Soluzione poco leggibile e poco interpretabile 10/03/2017 54
Struttura di Iterazione (non controllata) Utilizzata per esprimere operazioni che si ripetono finchè una determinata condizione resta vera. Istruzione Pseudocodice Traduzione in C while Do..while finchè(sentinella=true) leggi costo aggiungi il costo al totale ripeti leggi costo aggiungi il costo al totale finchè(sentinella=true) while(costo!= -1){ scanf(«%d»,&costo); totale = totale + costo; } do { scanf(«%d»,&costo); totale = totale + costo; } while(costo!= -1); for finchè(sentinella=true) leggi costo aggiungi il costo al totale for(costo = 0; costo!= -1;) { scanf(«%d»,&costo); totale = totale + costo; } Suggerimento: while e do...while si tendono a preferire per le iterazioni non controllate, mentre il for è la struttura più semplice da adottare quando sappiamo a priori il numero di iterazioni da eseguire è noto. 10/03/2017 55
Soluzione (con while + valore sentinella) 10/03/2017 56
Soluzione (con while + valore sentinella) Quesito: perchè sono necessarie le istruzioni alla riga 8 e 9? Non si poteva partire direttamente con il while? 10/03/2017 57
Soluzione (con while + valore sentinella) Quesito: perchè sono necessarie le istruzioni alla riga 8 e 9? Non si poteva partire direttamente con il while? Questo è un esempio di programmazione difensiva 10/03/2017 58
Recap: operatori di assegnamento Siano: int c = 3, d = 5, e = 4, f = 6, g = 12; Operatore di assegnamento Esempio di espressione Spiegazione Assegna += c += 7 c = c + 7 10 a c -= d -= 4 d = d - 4 1 a d *= e *= 5 e = e * 5 20 a e /= f /= 3 f = f / 3 2 a f %= g %= 9 g = g % 9 3 a g Fig. 3.11 Operatori aritmetici di assegnamento. Sono più efficienti perché riducono gli accessi in memoria non creando oggetti temporanei 10/03/2017 59
Recap: precedenza degli operatori Operatori Associatività Tipo ++ -- + -! (type) right to left unary * / % left to right multiplicative + - left to right additive < <= > >= left to right relational ==!= left to right equality && left to right logical AND left to right logical OR?: right to left conditional = += -= *= /= %= right to left assignment, left to right comma Fig. 4.16 Precedenza tra operatori e associatività. 10/03/2017 60
Recap Domande? Laboratorio di Informatica docente: Cataldo Musto cataldo.musto@uniba.it Cataldo Musto - Utilizzo di Eclipse CDT 10/03/2017 61
Esercitazione 1 Obiettivo: utilizzare i concetti base di programmazione strutturata, combinando istruzioni di iterazione e selezione per risolvere problemi complessi. Dimostrare anche di avere conoscenza relativa alla tipizzazione. Assignment su Repl.it 10/03/2017 62 Cataldo Musto - Utilizzo di Eclipse CDT
Esercitazione 1 Il Body Mass Index (BMI) è calcolato come il rapporto tra il peso e il quadrato dell altezza (espresso in metri) di un individuo Scrivere un algoritmo che acquisisca in input età, altezza e peso di dieci individui, e calcoli il BMI di ciascuno di essi e lo mostri sullo schermo. L algoritmo deve calcolare il massimo di altezza e peso e la media del BMI, distinguendo minorenni e maggiorenni L algoritmo deve anche stampare in output i valori massimi di altezza e peso (per le due categorie) e infine stampare un messaggio sullo schermo del tipo «Il campione è mediamente sovrappeso» oppure «il campione è mediamente sottopeso» a seconda che il BMI medio sia maggiore o minore di 25 (sia per i minorenni che per i maggiorenni). Modificare l algoritmo utilizzando un valore sentinella invece di un ciclo con valore predefinito Porre attenzione alla scelta dei tipi di dato di ogni variabile e all eventuale definizione di costanti che possono essere utili all algoritmo Commentare adeguatamente il codice e motivare nei commenti le scelte operate in termini algoritmici e in termini di tipi di dato scelti per le variabili 10/03/2017 63 Cataldo Musto - Utilizzo di Eclipse CDT