21 marzo 2002 (ri-)Avvisi: • Giovedi 28 marzo la lezione e’ sospesa. • Nuovo indirizzo di e-mail: [email protected] Spedire messaggi e esercizi solo qui!!! La struttura di selezione multipla switch • Formato switch ( variabile ){ case val-1: azioni case val-2: azioni …… case val-k: azioni default: azioni } val-1, val-2,…… val-k sono k valori di costanti intere per variabile 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 /* Fig. 4.7: fig04_07.c Counting letter grades */ #include <stdio.h> Sommario int main() { int grade; int aCount = 0, bCount = 0, cCount = 0, dCount = 0, fCount = 0; printf( printf( "Enter the letter grades.\n" ); "Enter the EOF character to end input.\n" 1. Inizializzazione ); while ( ( grade = getchar() ) != EOF ) { switch ( grade ) { /* switch nested in while */ case 'A': case 'a': ++aCount; break; /* grade was uppercase A */ /* or lowercase a */ case 'B': case 'b': ++bCount; break; /* grade was uppercase B */ /* or lowercase b */ case 'C': case 'c': ++cCount; break; /* grade was uppercase C */ /* or lowercase c */ case 'D': case 'd': ++dCount; break; /* grade was uppercase D */ /* or lowercase d */ 2. Input dei dati 2.1 switch loop per aggiornare count 33 34 case 'F': case 'f': 35 ++fCount; 36 break; /* or lowercase f */ 2.1 37 38 case '\n': case' ': 39 /* ignore these in input */ 3. Print results 41 default: /* catch all other characters */ 42 printf( "Incorrect letter grade entered." ); 43 printf( " Enter a new grade.\n" ); 44 break; 45 } } 47 48 printf( "\nTotals for each letter grade are:\n" ); 49 printf( "A: %d\n", aCount ); 50 printf( "B: %d\n", bCount ); 51 printf( "C: %d\n", cCount ); 52 printf( "D: %d\n", dCount ); 53 printf( "F: %d\n", fCount ); 54 55 56 } Use switch loop to update count break; 40 46 Sommario /* grade was uppercase F */ return 0; Precisazione • while ( ( grade = getchar() ) != EOF ) EOF e’ il carattere “end-of-file” . Dipende dal sistema operativo: •MS-DOS ctrl-z •Unix ctrl-d Valore numerico di EOF e’ solitamente –1 (comunque un valore negativo) Le istruzioni break e continue • break – Causa una uscita immediata da una struttura while, for, do/while o switch – L’esecuzione del programma continua con la prima istruzione dopo la struttura – Uso consueto dell’istruzione break • Uscire prima da un loop • Saltare la parte rimanente della struttura switch 1 /* Fig. 4.12: fig04_12.c Sommario 2 Usare l’istruzione break in una structura for */ 3 #include <stdio.h> 4 5 int main() 1. Inizializzazione 6 { delle variabili 7 int x; 8 9 for ( x = 1; x <= 10; x++ ) { 2. Loop 10 11 if ( x == 5 ) 12 break; /* interrompe il ciclo solo 13 if x == 5 */ 14 15 printf( "%d ", x ); 3. Print 16 } 17 18 printf( "\n Broke out of loop at x== %d\“, x ); 19 return 0; 20 } 1 2 3 4 Broke out of loop at x== 5 Output Le istruzioni break e continue • continue – Salta le istruzioni restanti nel corpo di una struttura while, for , do/while • Procede con l’iterazione successiva nel loop – while , do/while • La condizione di continuazione del ciclo e’ valutata immediatamente dopo che viene eseguita l’istruzione continue – for • Viene eseguita l’espressione di incremento, poi viene valutata la condizione di iterazione 1 /* Fig. 4.12: fig04_12.c 2 Uso di continue in una struttura for */ 3 #include <stdio.h> 4 5 int main() 6 { 7 int x; 8 9 for ( x = 1; x <= 10; x++ ) { 10 11 if ( x == 5 ) 12 continue; /* salta il codice restante del 13 ciclo solo if x == 5 */ 14 15 printf( "%d ", x ); 16 } 17 18 printf("\nUsed continue to skip printing value 5\n"); 19 return 0; 20 } 1 2 3 4 6 7 8 9 10 Used continue to skip printing the value 5 Sommario Inizializzazione delle variabili Loop Print Output Osservazioni su break e continue – break , continue violano le norme della programmazione strutturata, ma sono “tollerate” poiche’ sono piu’ efficienti (se usate bene!) delle corrispondenti tecniche strutturate…. Operatori Logici • && (AND logico ) – Restituisce true se entrambe le condizioni sono true • || (OR logico ) – Restituisce true se almeno una delle condizioni e’ true • ! (NOT logico, negazione logica) – Inverte la verita’/falsita’ della sua condizione – Operatore unario • Molto utili come condizioni per i loop Espressione true && false true || false !false Risultato false true true Confondere l’operatore di uguaglianza (==) con l’operatore di assegnamento (=) • Errore pericoloso – Non causano generalmente errori di sintassi – Ogni espressione che produce un valore puo’ essere usata in una struttura di controllo – Valori Nonzero sono true, Valori zero sono false • Esempio: if ( payCode == 4 ) printf( "You get a bonus!\n" ); – Controlla paycode, se e’ 4 allora viene dato un bonus Confondere l’operatore di uguaglianza (==) con l’operatore di assegnamento (=) • Se sostituiamo == con = if ( payCode = 4 ) printf( "You get a bonus!\n" ); – Questo assegna a paycode il valore 4 – 4 e’ nonzero, dunque l’espressione e’ true, e il bonus viene dato indipendentemente da quanto fosse il valore di paycode – Errore logico, non di sintassi Programmazione Strutturata • Tutti i programmi si possono dividere in tre parti: Sequenza Selezione - if, if/else, o switch Iterazione - while, do/while, or for Ogni selezione si puo’ riscrivere come istruzione if, Ogni iterazione si puo’ riscrivere come istruzione while • I programmi si possono ridurre a : – Sequenza – Struttura if (selezione) – Struttura while (iterazione) • Le strutture di controllo si possono combinare solo in due modi: nidificazione (reg. 2) e accatastamento (reg.3) Le funzioni • Divide et impera – Costruire un programma da piccoli pezzi detti moduli – Ogni pezzo e’ “maneggiabile” piu’ facilmente dell’intero problema. Funzioni – Moduli di programmi in C – Programmi vengono scritti combinando funzioni definite dall’utente e funzioni della libreria • La libreria standard del C ha una grande varieta’ di funzioni • Rende il lavoro del programmatore piu’ semplice…. … si evita di riinventare la ruota… Funzioni • Chiamate di funzioni – Specifica il nome della funzione e delle informazioni (gli argomenti) necessari per la sua esecuzione. – Esegue operazioni o manipolazioni – Restituisce dei risultati • Una analogia – Il boss chiede all’operaio di svolgere un compito – L’operaio prende le informazioni necessarie, svolge il compito e riporta i risultati – Information hiding: il boss non conosce i dettagli Funzioni della libreria matematica • Per eseguire tutti i comuni calcoli matematici – #include <math.h> • Formato per la chiamata di funzioni – FunctionName (argument); • Vari argomenti si scrivono separati da virgola – printf( "%.2f", sqrt( 900.0 ) ); • Chiama la funzione sqrt, che calcola la radice quadrata del suo argomento • Tutte le funzioni matematiche restituiscono un tipo double – Gli argomenti possono essere costanti, variabili o espressioni. Funzioni • Tutte le variabili dichiarate all’interno di funzioni sono variabili locali . – Note solo nella definizione della funzione • Parametri – Comunicano informazioni tra funzioni Definizione di funzioni • Formato per definizione di funzioni tipo-restituito nome-funzione( lista-parametri ) { dichiarazioni e istruzioni } Definizione di funzioni – Tipo-restituito: tipo di dato del risultato (default int) •void – la funzione non restituisce nulla – Nome-funzione: qualunque nome di identificatore valido Definizione di funzioni – Lista-parametri: dichiarazione dei parametri, separati da virgole che saranno ricevuti dalla funzione. • Se non deve ricevere alcun valore uso void oppure () • Ogni parametro deve essere specificato con il suo tipo (default int) NO! (float x, float y) (float x, y) SI! (float x,int y) Definizione di funzioni – Dichiarazioni e istruzioni: corpo della funzione (blocco) • Si possono dichiarare variabili all’interno di blocchi (variabili locali) • Non si puo’ dichiarare come variabile locale un parametro della funzione • Non si puo’ definire una funzione dentro un’altra funzione Definizione di funzioni – Ritorno del controllo • Se nulla deve essere restituito –return; – o, si raggiunge semplicemente la parentesi } • Se qualcosa deve essere restituito –return espressione; 1 /* Fig. 5.4: fig05_04.c 2 trovare il massimo di tre interi */ 3 #include <stdio.h> 4 5 int maximum( int, int, int ); /* prototipo 6 funzione */ 7 int main() 8 { 9 int a, b, c; 10 11 printf( "Enter three integers: " ); 12 scanf( "%d%d%d", &a, &b, &c ); 13 printf("Maximum is: %d\n", maximum( a, b, c )); 14 15 return 0; 16 } 17 18 /* Definizione della funzione massimo */ 19 int maximum( int x, int y, int z ) 20 { 21 int max = x; 22 23 if ( y > max ) 24 max = y; 25 26 if ( z > max ) 27 max = z; 28 29 return max; 30 } Sommario Prototipo Funzione (3 parametr) Input Chiamata funzione Definizione funzione Prototipi di funzioni – Nome della funzione – Parametri ricevuti dalla funzione – Tipo restituito dalla funzione (default int) – Si usano per validare le funzioni – Sono necessari solo se la definizione della funzione viene dopo il suo utilizzo nel programma int maximum( int, int, int ); • Prende 3 int • Restituisce int Header File (File di intestazione) • Header File – Contiene i prototipi delle funzioni di una certa libreria – <stdlib.h> , <math.h> , etc – Si includono con #include <filename> #include <math.h> • Header file personalizzati – – – – Creo file con i prototipi delle “mie” funzioni Lo salvo come filename.h Lo includo nei programmi con #include "filename.h" Permette di riutilizzare delle funzioni fatte da noi Generazione di numeri random • funzione rand – Si trova in <stdlib.h> – Restituisce un numero "random" 0 e RAND_MAX (almeno 32767) i = rand(); • Pseudorandom – Sequenza prefissata di numeri "random" – Stessa sequenza ogni volta che si chiama la funzione Generazione di numeri random • Scaling – Per avere un numero random tra number tra 1 e n 1 + ( rand() % n ) rand % n restituisce un numero tra 0 e n-1 1 + ( rand() % 6) // numero tra 1 e 6 Generazione di numeri random • funzione srand – Si trova in <stdlib.h> – Prende un intero seed – salta in una locazione della sequenza "random“ srand( seed ); – srand( time( NULL ) ); //load <time.h> • time( NULL )- ora corrente espressa in sec. 1 /* Fig. 5.9: fig05_09.c 2 Randomizing die-rolling program */ 3 #include <stdlib.h> 4 #include <stdio.h> 5 6 int main() 7 { 8 int i; 9 unsigned seed; 10 11 printf( "Enter seed: " ); 12 scanf( "%u", &seed ); 13 srand( seed ); 14 15 for ( i = 1; i <= 10; i++ ) { 16 printf( "%10d", 1 + ( rand() % 6 ) ); 17 18 if ( i % 5 == 0 ) 19 printf( "\n" ); 20 } 21 22 return 0; 23 } Sommario 1. Dichiara la variabile seed 2. Input valore per seed 2.1 Usa srand per cambiare la sequenza random 2.2 Definisce Loop 3. Genera e da’ in output numeri random Enter seed: 67 6 1 Sommario 1 6 4 1 6 6 2 4 Output Enter seed: 867 2 1 Enter seed: 67 6 1 4 1 6 3 1 6 6 2 1 6 4 1 6 6 2 4 Esercizi: • Esercizio 4.33 Scrivere un programma che visualizzi una tabella contenente tutti i numeri romani in corrispondenza dei numeri interi decimali da 1 a 100.