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