Corso di Esercitazioni di Programmazione Introduzione Dott.ssa Sabina Rossi Informazioni Pagina web del corso: http://www.dsi.unive.it/~prog1 News Orari Mailing list Lezioni Esercitazioni Date esami Risultati esami ….. Informazioni e spiegazioni Per ricevere gli avvisi relativi al corso ci si può iscrivere alla mailing list [email protected] usando la pagina web http://listserver.dsi.unive.it/wws/subrequest/programmazione oppure inviando direttamente una e-mail a [email protected] mettendo nel body il testo subscribe programmazione Ricevimento Martedì dalle 14.00 alle 15.00 oppure su appuntamento Libri di Testo C Corso completo di programmazione H.M. Deitel, P.J. Deitel Apogeo The C Programming Language Kernighan, Ritchie Prentice Hall Laboratorio Lunedì, Martedì, Mercoledì, Giovedì dalle 13.00 alle 14.00 Tutors: Lucia Gallina e Antonino Simone Laboratorio Richiesta dell’account: In aula 3 c'è un PC su un carrello rosso dove le matricole DEVONO iscriversi (inserendo Cognome, Nome, Numero di matricola, e eventuale Email); Coloro che non sono ancora iscritti e quindi non hanno il numero di matricola, come matricola devono scrivere "TEMP06" per ottenere un account provvisorio valido fino al 31/12. Esercitazioni settimanali Ogni settimana verranno assegnate delle esercitazioni da svolgere a casa Le esercitazioni devono essere consegnata via web (si veda la pagina web del corso) Esame L'esame consiste in due prove distinte: - una prova teorica scritta; - una prova pratica in laboratorio. Per passare l'esame entrambe le prove devono essere sufficienti, e verranno registrati due voti che sono la media dei due esami + un bonus per le esercitazioni svolte e consegnate durante l'anno. Si tratta di due prove indipendenti, il cui voto rimane valido per tutto l'anno accademico. Problemi, Algoritmi e Programmi Approfondiamo come progettare e scrivere nuovi algoritmi e programmi Risolvere un problema es : riconoscere qualcuno fra la folla Dati di ingresso Elaborazione Immagine della folla Ricerca nell’immagine Dati di uscita SI, NO, chi è la persona riconosciuta Risolvere un problema es : torta di carote Dati di ingresso Ingredienti Elaborazione Combinazione degli ingredienti secondo una opportuna ricetta Dati di uscita La torta ! Risolvere un problema – vogliamo essere capaci di specificare la strategia seguita dal passo di elaborazione in modo da farla eseguire ‘automaticamente’ dal computer quindi dobbiamo : – riuscire a descrivere accuratamente i vari passi della soluzione attraverso azioni che il calcolatore è in grado di effettuare e con un linguaggio che è in grado di comprendere Risolvere un problema Dati di ingresso Codificati opportunamente Umano (che conosce l’algoritmo) Dati di uscita Elaborazione Trasformazione dei dati di ingresso seguendo i passi specificati da un opportuno algoritmo Ovvero la descrizione dell’algoritmo secondo un linguaggio comprensibile al calcolatore Calcolatore programma (che conosce alcune azioni elementari: es confrontare due numeri, eseguire semplici operazioni aritmetiche Qual’è il ruolo dei calcolatori ? Nel loro impiego tradizionale, i calcolatori sono essenzialmente esecutori di soluzioni che esseri umani hanno previamente identificato e descritto Questo utilizzo è motivato dalla notevole velocità di esecuzione dei calcolatori e dalla loro capacità di eseguire molte volte la stessa operazione Un calcolatore è caratterizzato – dal linguaggio che è in grado di interpretare e – dalle istruzioni che è in grado di eseguire Introduzione alla programmazione • Prima di scrivere un programma: – Avere una piena comprensione del problema – Pianificare con cura un approccio per risolverlo • Mentre si scrive un programma: – Sapere quali “mattoni per costruire” sono disponibili – Seguire buoni principi di programmazione Algoritmi • Problemi di elaborazione – Possono essere risolti eseguendo, in un ordine specifico, una serie di azioni • Algoritmo: procedura in termini di – Azioni che devono essere eseguite – L’ordine in cui tali azioni devono essere eseguite Algoritmi e Programmi Algoritmo (def) : – una sequenza di azioni non ambigue che trasforma i dati iniziali nel risultato finale utilizzando un insieme di azioni elementari che possono essere eseguite da un opportuno esecutore. Programma (def) – specifica di un algoritmo utilizzando un linguaggio non ambiguo e direttamente comprensibile dal computer Pseudocodice – Linguaggio artificiale e informale, che aiuta i programmatori a sviluppare gli algoritmi – Simile all’italiano di tutti i giorni – Non realmente eseguito sui computer – Aiuta il programmatore a “riflettere” sul programma, prima che provi a scriverlo • Facilmente convertibile in un corrispondente programma C Strutture di controllo • Esecuzione sequenziale – Le istruzioni sono eseguite, una dopo l’altra, nell’ordine in cui sono state scritte • Trasferimento di controllo – Quando la prossima istruzione ad essere eseguita non è la prossima nella sequenza • Strutture di controllo – Tutti i programmi possono essere scritti in termini di tre sole strutture di controllo: • Struttura di sequenza: le istruzioni vengono eseguite sequenzialmente in modo implicito • Struttura di selezione: Se, Se…altrimenti • Struttura di iterazione: Finché Diagramma di flusso Sono grafici che permettono di esprimere un algoritmo in modo preciso ed intuitivo Si costruiscono a partire da un certo numero di ‘blocchi base’ che rappresentano le operazioni elementari ed i costrutti di controllo Diagramma di flusso I blocchi base: Inizio Sottoprog. Operazione I/0 Fine Si Cond. No Elaborazione Il comando di selezione Se • Struttura di selezione: – Usata per scegliere tra percorsi di azione alternativi – Pseudocodice: Se il voto dello studente è maggiore o uguale a 60 Visualizza “Promosso” • Se la condizione è vera – Sarà visualizzato “Promosso” ed “eseguita” l’istruzione sucessiva – Se falsa, la visualizzazione sarà ignorata e sarà eseguita l’istruzione successiva – I rientri rendono i programmi più semplici da leggere Il comando di selezione Se Simbolo rombo (simbolo di decisione) – Indica che dovrà essere eseguita una scelta – Contiene un’espressione che può essere vera o falsa – Testa la condizione, segue il percorso appropriato Il comando di selezione Se … altrimenti • Se – Esegue l’azione indicata solo quando la condizione è vera • Se…altrimenti – Specifica che, nel caso in cui la condizione sia vera, dovrà essere eseguita una azione differente da quella che si dovrà eseguire qualora la condizione sia falsa • Pseudocodice: Se il voto dello studente è maggiore o uguale a 60 Visualizza “Promosso” altrimenti Visualizza “Bocciato” – Osservate le convenzioni di rientro e spaziatura Il comando di selezione Se … altrimenti • Diagramma di flusso del comando di selezione I comandi Se … altrimenti nidificati Se il voto dello studente è maggiore o uguale a 90 Visualizza “A” altrimenti Se il voto dello studente è maggiore o uguale a 80 Visualizza “B” altrimenti Se il voto dello studente è maggiore o uguale a 70 Visualizza “C” altrimenti Se il voto dello studente è maggiore o uguale a 60 Visualizza “D” altrimenti Visualizza “F” Il comando di iterazione Finché • Comando di iterazione – Consente al programmatore di specificare che una azione dovrà essere ripetuta finché alcune condizioni rimarranno vere – Pseudocodice: Finché ci sono ancora articoli nella mia lista della spesa Compra il prossimo articolo e cancellalo dalla mia lista – Il ciclo finché sarà ripetuto fino a che la condizione diventi falsa Il comando di iterazione Finché • Esempio int product = 2; while (product <= 1000) product = 2 * product; Iterazione controllata da un contatore – Ciclo ripetuto fino a che un contatore raggiunge un certo valore – Iterazione definita: il numero delle iterazioni è noto – Esempio: Una classe di dieci studenti sostiene un esame. Avete a disposizione le votazioni (degli interi nell’intervallo da 0 a 100) per questo esame. Determinare la media della classe in questo esame. – Pseudocodice: Inizializzare il totale a zero Inizializzare il contatore dei voti a uno Finchè il contatore resta minore o uguale a dieci Prendere dall’input il prossimo voto Aggiungere il voto al totale Aggiungere uno al contatore Impostare il valore della media al totale diviso dieci Visualizzare la media Formulazione degli algoritmi con il processo top-down per raffinamenti successivi Sviluppate un programma per il calcolo della media di una classe, che elaborerà un numero arbitrario di votazioni ogni volta che il programma sarà eseguito. – Il numero di studenti é sconosciuto a priori – In quale modo il programma potrà determinare quando terminare l’immissione delle votazioni? • Si usa un valore sentinella – Anche chiamato valore di segnalazione, valore fittizio o valore bandiera – Indica la “fine della immissione dei dati” – L’iterazione finisce quando l’utente inserisce il valore sentinella – Il valore sentinella dovrà essere scelto in modo che non possa essere confuso con un valore di input accettabile (come -1 in questo caso) Formulazione degli algoritmi con il processo top-down per raffinamenti successivi Raffinamenti successivi top down – Cominciamo con una rappresentazione in pseudocodice del top: Determinare la media della classe per l’esame – Dividiamo il top in piccole attività e elenchiamole in ordine: Inizializzare le variabili Prendere in input, sommare e contare le votazioni dell’esame Calcolare e visualizzare la media della classe • Molti programmi hanno tre fasi: – Inizializzazione: inizializza le variabili del programma – Elaborazione: prende in input i valori dei dati e imposta conseguentemente le variabili del programma – Chiusura: calcola e visualizza i risultati finali Formulazione degli algoritmi con il processo top-down per raffinamenti successivi Raffiniamo la fase di inizializzazione da Inizializzare le varibili in: Inizializzare il totale a zero Inizializzare il contatore a zero • Raffiniamo Prendere in input, sommare e contare le votazioni dell’esame in: Prendere in input la prima valutazione (o forse il valore sentinella) Finché l’utente non ha ancora immesso il valore sentinella Aggiungere questa valutazione al totale corrente Aggiungere uno al contatore di valutazioni Prendere in input la prossima valutazione (o forse il valore sentinella) Formulazione degli algoritmi con il processo top-down per raffinamenti successivi Raffiniamo Calcolare e visualizzare la media della classe in: Se il contatore non è uguale a zero Impostare la media con il totale diviso per il contatore Visualizzare la media altrimenti Visualizzare “Non sono state immesse valutazioni” Formulazione degli algoritmi con il processo top-down per raffinamenti successivi Inizializzare il totale a zero Inizializzare il contatore a zero Prendere in input la prima valutazione (o forse il valore sentinella) Finché l’utente non ha ancora immesso il valore sentinella Aggiungere questa valutazione al totale corrente Aggiungere uno al contatore di valutazioni Prendere in input la prossima valutazione (o forse il valore sentinella) Se il contatore non è uguale a zero Impostare la media con il totale diviso per il contatore Visualizzare la media altrimenti Visualizzare “Non sono state immesse valutazioni” Diagramma di flusso I blocchi base vengono collegati tramite ‘frecce’ che collegano un’azione alla successiva all’interno dell’algoritmo Vediamo i diagrammi di flusso dei seguenti algoritmi: 1. Trovare il maggiore fra 2 numeri interi x e y 2. Trovare il massimo fra N numeri Il maggiore fra due numeri interi x, y Algoritmo max 1. Leggi i valori di x e y dall’esterno 2. Calcola la differenza d fra x e y (d=x-y) 3. Se d è maggiore di 0 allora esegui il passo 4 altrimenti esegui il passo 5 4. Stampa ‘il massimo è …’ seguito dal valore di x e termina 5. Stampa ‘il massimo è …’ seguito dal valore di y e termina DF di max Inizio Leggi x e y d=x-y Si d>0? No Scrivi ‘max è’ y Scrivi ‘max è’ x Fine DF di max Inizio Passo 1 Leggi x e y Passo 2 d=x-y Si Passo 3No d>0? Scrivi ‘max è’ y Scrivi ‘max è’ x Passo 5 Passo 4 Fine Determinare il massimo fra N numeri interi Algoritmo max_N 1. Leggi il valore di N dall’esterno 2. Leggi i primi due numeri 3. Trova il maggiore m fra i primi due numeri (con max) 4. Finchè (hai esaminato meno di N numeri) • a. Leggi un nuovo numero x • b. Trova il maggiore fra m e x usando l’algoritmo max • c. Assegna il valore del maggiore a m 5. Stampa ‘il massimo è…’ ed il valore di m e termina DF per il problema del massimo di N numeri Inizio Leggi i primi due numeri e memorizzali nelle variabili a e b m = max(a,b) Si Leggi un nuovo numero in a Ancora numeri da esaminare ? No Scrivi ‘max è m’ Fine m = max(a,m) Supponiamo N fissato DF e programmi I DF sono un primo passo verso la formalizzazione di un algoritmo in modo non ambiguo Per ottenere una codifica interpretabile direttamente dalla macchina dobbiamo però specificare molti più dettagli : – trasformare tutte le ‘frasi’ in variabili e modifiche su di esse : • es : ‘ancora numeri da esaminare’ deve essere tradotto in qualcosa di calcolabile dalla macchina usando solo le operazioni elementari Leggi N Inizio Leggi i primi due numeri e memorizzali nelle variabili a e b m = max(a,b) Si I<N? I=I+1 I=2 No Scrivi ‘max è m’ Leggi un nuovo numero in a m = max(a,m) Fine DF per il problema del massimo di N numeri (seconda versione) Supponiamo N almeno 2 Programmi Per ottenere una codifica interpretabile direttamente dalla macchina dobbiamo anche : – decidere come codificare l’informazione • non banale in esempi più complessi del nostro, ad esempio se voglio codificare un’immagine o un video – scrivere il tutto con una codifica ‘leggibile’ dalla macchina • … ma la macchina lavora molto a basso livello (linguaggio macchina, codificato con zeri e uni) !!!! Programmi … soluzione…. – usare linguaggi di ‘livello’ più alto (linguaggi di programmazione ad alto livello) – usare dei programmi appositi per far tradurre i nostri programmi in linguaggio macchina (i compilatori) importante …. – I tipici linguaggi (C, Java, Fortran, Basic…) permettono di definire strutture del tutto analoghe ai diagrammi di flusso che abbiamo visto finora Programma: max in C main() /* calcola max */ { int x, y, d; scanf ("%d %d”, &x, &y) ; d=x-y; if (d > 0) printf (”il max è %d”, &x) ; else printf (”il max è %d”, &y) ; return ; } Programma: max_N in C main() /* calcola max_N */ { int m, i, a, b; i=2; scanf ("%d %d”, &a, &b); m = max(a,b); while (i < N) { scanf ("%d ”, &a) ; m = max(a,m); i = i+1; } printf (”il max è %d”, &m) ; return ; } Programma: max_N in C (cont.) int max(int x, int y) /* sottoprogramma che calcola max */ { int d; d=x-y; if (d > 0) return x; else return y; }