INFORMATICA 1 Corso di Laurea in Fisica a.a. …3. Data la struttura di una rete stradale e le...
Transcript of INFORMATICA 1 Corso di Laurea in Fisica a.a. …3. Data la struttura di una rete stradale e le...
INFORMATICA 1Corso di Laurea in Fisica
a.a. 2007/08
prof. Paolo Mancarella
1Dipartimento di Informaticaemail: [email protected]
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 1
Introduzione al corso Informazioni utili
Informazioni utiliI Ricevimento studenti: MERCOLEDI’ 15-18I email: [email protected] Materiale didattico: questi lucidi
pagina web corso:http://www.di.unipi.it/∼paolo/Informatica1/Testi consigliati per consultazione:
I Ceri-Mandrioli-SbattellaInformatica: programmazioneMcGraw-Hill
I Kelley-PohlC: didattica e programmazioneAddison Wesley
I Crescenzi-Gambosi-GrossiStrutture di dati e algoritmiAddisonWesley
I Modalita d’esameProva scritta (o due compitini)Prova orale (con voto >= 16 allo scritto)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 2
Introduzione al corso Programma di massima del corso
Programma di massima del corso
I Concetti di base della programmazione
I Rappresentazione dell’informazione (cenni)
I Architettura degli elaboratori (cenni)
I La programmazione nel linguaggio C
I Cenni di programmazione ricorsiva
I Cenni di complessita computazionale
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 3
Concetti di base della programmazione Cosa e?
Cosa intendiamo per programmazione
I I calcolatori sono macchine in grado di eseguire velocemente e conprecisione sequenze di operazioni elementari.
I A differenza di altre macchine automatiche (es. lavatrici, calcolatricitascabili, registratori di cassa, ecc.) i calcolatori sono programmabili:la funzione svolta di volta in volta dipende dal particolare programmacon cui l’utente istruisce la macchina per la soluzione di un problema.
I Un programma e una sequenza di operazioni necessarie per risolvereun problema, espressa in un linguaggio di programmazione che ilcalcolatore e in grado di comprendere ed eseguire.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 4
Concetti di base della programmazione Cosa e?
Cosa intendiamo per programmazione
I Il procedimento che porta alla definizione dei programmi adatti arisolvere problemi e detto programmazione.
I I concetti che stanno alla base della programmazione si possonospiegare e comprendere senza far riferimento al calcolatore.
I La programmazione e tuttavia divenuta una vera e propria disciplinasolo con l’avvento dei moderni calcolatori elettronici.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 5
Concetti di base della programmazione Le fasi della programmazione
Le fasi della programmazione
Ad un primo livello di astrazione l’attivita della programmazione puoessere suddivisa in quattro (macro) fasi principali.
1. Definizione del problema (specifica)
2. Individuazione di un procedimento risolutivo (algoritmo)
3. Codifica dell’algoritmo in un linguaggio di programmazione (codifica)
4. Esecuzione e messa a punto (esecuzione)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 6
Concetti di base della programmazione Le fasi della programmazione
Specifica
I La prima fase della programmazione consiste nel comprendere edefinire (specificare) il problema che si vuole risolvere.
I La specifica del problema puo essere fatta in maniera piu o menorigorosa, a seconda del formalismo descrittivo utilizzato.
I La specifica di un problema prevede la descrizione dello stato inizialedel problema (dati iniziali, input) e dello stato finale atteso (i risultati,output).
I La caratterizzazione degli stati iniziale e finale dipende dal particolareproblema in esame e dagli oggetti di interesse.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 7
Concetti di base della programmazione Le fasi della programmazione
Esempi di specifica informale
1. Dati due numeri, trovare il maggiore.
2. Dato un elenco telefonico e un nome, trovare il numero di telefonocorrispondente.
3. Data la struttura di una rete stradale e le informazioni sui flussi deiveicoli, determinare il percorso piu veloce da A a B.
4. Scrivere tutti i numeri pari che non sono la somma di due numeriprimi (Congettura di Goldbach).
5. Decidere per ogni programma e per ogni dato in ingresso, se ilprogramma C termina quando viene eseguito su quel dato.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 8
Concetti di base della programmazione Le fasi della programmazione
Esempi (contd.)
Caratteristiche comuni ai problemi
informazioni in ingresso =⇒ informazioni in uscitastato iniziale =⇒ stato finale
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 9
Concetti di base della programmazione Le fasi della programmazione
Osservazioni sulla formulazione dei problemi:
I la descrizione non fornisce un metodo risolutivo (es. 3 )
I la descrizione del problema e talvolta ambigua o imprecisa (es. 2, conMario Rossi che compare piu volte )
I per alcuni problemi non e noto un metodo risolutivo (es. 4 )
I esistono problemi per i quali e stato dimostrato che non puo esistereun metodo risolutivo (es. 5 )�
��
Noi considereremo solo problemi per i qualie noto che esiste un metodo risolutivo.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 10
Concetti di base della programmazione Le fasi della programmazione
Algoritmi
I Una volta specificato il problema, si determina un procedimentorisolutivo dello stesso (algoritmo), ovvero un insieme di azioni daintraprendere per ottenere i risultati attesi.
I Il concetto di algoritmo ha origini molto lontane: l’uomo ha utilizzatospesso algoritmi per risolvere problemi di varia natura. Solo in eramoderna, tuttavia, ci si e posti il problema di caratterizzare problemie classi di problemi per i quali e possibile individuare una soluzionealgoritmica e solo nel secolo scorso e stato dimostrato che esistonoproblemi per i quali non e possibile individuare una soluzionealgoritmica.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 11
Concetti di base della programmazione Le fasi della programmazione
Algoritmi (cont.)
I Utilizziamo algoritmi nella vita quotidiana tutte le volte che, adesempio, seguiamo le istruzioni per il montaggio di unaapparecchiatura, per la sostituzione della cartuccia di una stampante,per impostare il ciclo di lavaggio di una lavastoviglie, per prelevarecontante da uno sportello Bancomat, ecc.
��
��
Un algoritmo e una sequenza di passi che, se intrapresada un esecutore, permette di ottenere i risultati attesi
a partire dai dati forniti.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 12
Concetti di base della programmazione Le fasi della programmazione
Proprieta di un algoritmo
La descrizione di un procedimento risolutivo puo considerarsi unalgoritmo se rispetta alcuni requisiti essenziali, tra i quali:
Finitezza: un algoritmo deve essere composto da una sequenzafinita di passi elementari.
Eseguibilita: il potenziale esecutore deve essere in grado di eseguireogni singola azione in tempo finito con le risorse adisposizione
Non-ambiguita: l’esecutore deve poter interpretare in modo univocoogni singola azione.
Tipici procedimenti che non rispettano alcuni dei requisiti precedentisono:
I le ricette di cucina: aggiungere sale q.b. - non rispetta 3)I le istruzioni per la compilazione della dichiarazione dei redditi (!)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 13
Concetti di base della programmazione Le fasi della programmazione
Codifica
I Questa fase consiste nell’individuare una rappresentazione deglioggetti di interesse del problema ed una descrizione dell’algoritmo inun opportuno linguaggio noto all’esecutore.
I Nel caso in cui si intenda far uso di un elaboratore per l’esecuzionedell’algoritmo, quest’ultimo deve essere tradotto (codificato) in unopportuno linguaggio di programmazione. Il risultato in questo caso eun programma eseguibile al calcolatore.
I Quanto piu il linguaggio di descrizione dell’algoritmo e vicino allinguaggio di programmazione scelto, tanto piu semplice e la fase ditraduzione e codifica. Se addirittura il linguaggio di descrizionecoincide con il linguaggio di programmazione, la fase di traduzione esuperflua.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 14
Concetti di base della programmazione Le fasi della programmazione
Codifica (cont.)
I linguaggi di programmazione forniscono strumenti linguistici perrappresentare gli algoritmi sottoforma di programmi che possanoessere compresi da un calcolatore.
In particolare dobbiamo rappresentare nel linguaggio diprogrammazione
I l’algoritmo
I le informazioni iniziali
I le informazioni utilizzatedall’algoritmo
I le informazioni finali
=⇒ programma
=⇒ dati in ingresso
=⇒ dati ausiliari
=⇒ dati in uscita
In questo corso impareremo a codificare algoritmi utilizzando illinguaggio di programmazione denominato C.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 15
Concetti di base della programmazione Le fasi della programmazione
Esecuzione
I La fase conclusiva consiste nell’esecuzione vera e propria delprogramma.
I Spesso questa fase porta alla luce errori che possono coinvolgereciascuna delle fasi precedenti, innescando un procedimento di messa apunto tale da richiedere la revisione di una o piu fasi (dalla specifica,alla definizione dell’algoritmo, alla codifica di quest’ultimo).
I Nel caso dei linguaggi di programmazione moderni, vengono fornitistrumenti (denominati di solito debugger) che aiutano nellaindividuazione degli errori e nella messa a punto dei programmi.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 16
Concetti di base della programmazione Le fasi della programmazione
Esempi
Negli esempi che seguono, utilizziamo un linguaggio pseudo-naturale perla descrizione degli algoritmi.
Tale linguaggio utilizza, tra l’altro, le comuni rappresentazioni simbolichedei numeri e delle operazioni aritmetiche.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 17
Concetti di base della programmazione Le fasi della programmazione
Problema 1: Calcolo del prodotto di due interi positivi
SpecificaInput: due valori interi positivi A e BOutput: il valore di A×B
AlgoritmoSe l’esecutore che scegliamo e in grado di effettuare tutte leoperazioni di base sui numeri, un semplice algoritmo e il seguente:
Passo 1. Acquisisci il primo valore, sia esso APasso 2. Acquisisci il secondo valore, sia esso BPasso 3. Ottieni il risultato dell’operazione A×B
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 18
Concetti di base della programmazione Le fasi della programmazione
Problema 1 (cont.)
CodificaUn esecutore che rispetta le ipotesi precedenti e una persona dotatadi una calcolatrice tascabile. La codifica dell’algoritmo in questo casopuo essere allora la seguente:
Passo 1. Digita in sequenza le cifre decimali del primo valorePasso 2. Digita il tasto ∗Passo 3. Digita in sequenza le cifre decimali del secondo valorePasso 4. Digita il tasto =
Esecuzione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 19
Concetti di base della programmazione Le fasi della programmazione
Problema 1 (cont.)
I Supponiamo ora che l’esecutore scelto sia in grado di effettuare solole operazioni elementari di somma, sottrazione, confronto tra numeri.
I E necessario individuare un nuovo procedimento risolutivo che tengaconto delle limitate capacita dell’esecutore
Algoritmo 2Passo 1. Acquisisci il primo valore, sia esso APasso 2. Acquisisci il secondo valore, sia esso BPasso 3. Associa 0 ad un terzo valore, sia esso CPasso 4. Finche B>0 ripeti
Passo 4.1. Somma a C il valore APasso 4.2. Sottrai a B il valore 1
Passo 5. Il risultato e il valore C
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 20
Concetti di base della programmazione Le fasi della programmazione
Problema 1: (cont.)
Un esecutore che rispetta le ipotesi precedenti e un bimbo in grado dieffettuare le operazioni richieste (somma, sottrazione e confronto) e diriportare i risultati di semplici calcoli su un quaderno.Codifica
Passo 1. Scrivi il primo numero nel riquadro APasso 2. Scrivi il secondo numero nel riquadro BPasso 3. Scrivi il valore 0 nel riquadro CPasso 4. Ripeti i seguenti passi finche il valore nel
riquadro B e maggiore di 0:- calcola la somma tra il valore in A e il valore in C- scrivi il risultato ottenuto in C- calcola la differenza tra il valore in B ed il numero 1- scrivi il risultato ottenuto in B
Passo 5. Il risultato e quanto contenuto nel riquadro C.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 21
Concetti di base della programmazione Il concetto di stato
Il concetto di stato
Gli esempi visti finora consentono di fare le seguenti considerazioni dicarattere generale:
I La specifica (astratta) di un problema consiste nella descrizione diuno stato iniziale (che descrive i dati del problema) e di uno statofinale (che descrive i risultati attesi).
I E necessario individuare una rappresentazione degli oggetti coinvolti(e dunque dello stato) che sia direttamente manipolabiledall’esecutore prescelto.
I Un algoritmo e una sequenza di passi elementari che, se intrapresi daun esecutore, comportano ripetute modifiche dello stato fino alraggiungimento dello stato finale desiderato.
I Le azioni di base che l’esecutore e in grado di effettuare devonodunque prevedere, tra le altre, azioni che hanno come effettocambiamenti dello stato.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 22
Concetti di base della programmazione Il concetto di stato
Un’astrazione dello stato
Introduciamo una possibile astrazione del concetto di stato, di cui faremospesso uso in seguito.
Stato
Uno stato e un insieme di associazioni tra nomi simbolici e valori.
In uno stato, ad ogni nome simbolico e associato al piu un valore.
Rappresentiamo una associazione tra il nome simbolico x ed il valore valcon la notazione �� ��x val
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 23
Concetti di base della programmazione Il concetto di stato
Lo stato: esempi
Stati correttiI {nome Antonio, cognome Rossi, eta’ 25}I {importo $1650, tasso 10%, interesse $165 }I {a 25, b 3, c 50}
Stati non correttiI {nome Antonio, nome Paolo, eta’ 25}I {b 45, a 150, b 10}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 24
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Pseudo-linguaggio
I Utilizziamo inizialmente uno pseudo-linguaggio con un insieme dicostrutti linguistici che costituiscono il nucleo di un qualunquelinguaggio di programmazione reale.
I Senza entrare in eccessivi dettagli formali, nel presentare le notazioniutilizzate (sintassi) diamo anche una descrizione informale(semantica) di cio che accade al momento dell’esecuzione incorrispondenza dei vari costrutti.
Il linguaggio contiene costrutti per:
I rappresentare semplici calcoli attraverso le comuni operazionilogico/aritmetiche (espressioni)
I modificare le associazioni nello stato (assegnamento e ingresso)
I controllare l’ordine di esecuzione delle azioni (controllo)
I fornire i risultati (produzione in uscita dello stato finale)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 25
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Espressioni
Espressioni NumericheIl linguaggio consente di rappresentare semplici calcoli algebrici,attraverso le usuali espressioni costruite a partire dai valori numerici edalle operazioni di
somma +sottrazione -prodotto *divisione intera /resto della divisione intera %.
Il significato di un’espressione e il suo valore ottenuto secondo leusuali regole di calcolo.Esempio:
il valore di 3 ∗ 5 + 6 e 21il valore di 3 ∗ (5 + 6) e 33
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 26
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Espressioni (cont.)
Oltre ai valori numerici, le espressioni possono contenere nomi simbolici: ilcalcolo di un’espressione che contiene un nome simbolico x dipende dallostato, e precisamente dal valore associato al nome x nello stato.
Esempio:il valore di 3 ∗ (5 + x) e
I 33 in uno stato che contiene l’associazione x 6
I 18 in uno stato che contiene l’associazione x 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 27
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Espressioni (cont.)
Espressioni BooleaneIl linguaggio consente poi di rappresentare condizioni ovveroespressioni il cui valore e un valore di verita (true o false).
Le condizioni sono costruite attraverso le usuali operazioni diconfronto (==, ! =, <, >, <=, >=) e, come nel caso delleespressioni aritmetiche, il loro valore puo dipendere dallo stato.Esempio: il valore di y==x+1 e
I true in uno stato che contiene le associazioni x 5 e y 6I false in uno stato che contiene le associazioni x 5 e y 9
Condizioni piu complesse possono essere costruite attraversooperatori logici quali negazione (simbolo !), congiunzione (simbolo&&) e disgiunzione (simbolo ||).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 28
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Espressioni (cont.)
I Significato di ! - il valore di verita di ! P eI true se il valore di verita di P e falseI false se il valore di verita di P e true
I Significato di && - il valore di verita di P && Q eI true se i valori di verita di P e Q sono entrambi trueI false altrimenti
I Significato di || - il valore di verita di P || Q eI false se i valori di verita di P e Q sono entrambi falseI true altrimenti
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 29
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Esempio:I Il valore di (y >= x) &&(x > 5) e
- true in uno stato che contiene le associazioni x 15 e y 30- false in uno stato che contiene le associazioni x 3 e y 30
I Il valore di (y >= x) || (x > 5) e
- true in uno stato che contiene le associazioni x 2 e y 30- false in uno stato che contiene le associazioni x 3 e y 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 30
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Modifica dello stato: ASSEGNAMENTO
I L’istruzione che consente di rappresentare modifiche di stato eusualmente nota come assegnamento.
I L’assegnamento consente di cambiare un’associazione nello stato,ovvero il valore associato nello stato ad un nome simbolico.
I Useremo per l’assegnamento la seguente notazione�� ��x = exp;
dove x e un nome simbolico e exp una espressione.I L’esecuzione dell’assegnamento x = exp; consiste nel
(i) calcolare il valore, sia esso val, dell’espressione exp(ii) introdurre nello stato l’associazione x val
I Si noti che (ii) comporta la rimozione dallo stato della eventualeassociazione gia presente per il nome simbolico x (si parla a questoproposito di assegnamento distruttivo).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 31
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
ASSEGNAMENTO: esempi
Vediamo alcuni esempi, indicando lo stato prima e dopo l’esecuzionedegli assegnamenti proposti. Le associazioni modificate nello statofinale sono evidenziate in verde.
Stato iniziale Assegnamento Stato Finale
{ x 10, y 20} x = 5; { x 5, y 20}{ x 10, y 20} x = y*2; { x 40, y 20}{ x 10, y 20} x = x+1; { x 11, y 20}
Si noti come, nel terzo esempio, lo stesso nome simbolico x giochi unduplice ruolo:
- a destra del simbolo = indica un valore (il valore associato ad x nellostato iniziale)
- a sinistra del simbolo = indica l’associazione da modificare nello statoa seguito dell’assegnamento.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 32
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Modifica dello stato: INPUT
I La seconda istruzione di modifica dello stato consente di acquisirevalori dal mondo esterno al momento dell’esecuzione. La notazioneutilizzata e �� ��Input(x);
dove x indica un nome simbolico.I L’esecuzione consiste nel:
(i) Acquisire un nuovo valore, sia esso val(ii) Introdurre nello stato l’associazione x val
I Come nel caso dell’assegnamento, il punto (ii) comporta la rimozionedallo stato dell’eventuale associazione gia presente per il nomesimbolico x
I La presenza di tale istruzione permette di descrivere algoritmi generaliin cui non tutti i dati sono noti a priori, ma lo saranno solo almomento dell’esecuzione.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 33
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Istruzioni di controllo: SEQUENZAI Negli esempi visti in precedenza gli algoritmi sono stati descritti come
sequenze di passi elementari del tipoPasso 1. azione 1Passo 2. azione 2. . .
I Abbiamo utilizzato una sorta di numerazione per indicare l’ordine diesecuzione delle varie azioni: prima azione 1 poi azione 2 poi ....
I Nel linguaggio che stiamo introducendo, secondo le convenzionisintattiche del C, una sequenza di azioni viene rappresentatamediante un blocco #
"
!
{istruzione 1istruzione 2. . .istruzione n}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 34
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
SEQUENZA (cont.)
I Scriveremo dunque{istruzione 1istruzione 2. . .}
ad indicare che l’ordine di esecuzione dei singoli passi e quello testualedel programma.
I Si noti che ogni istruzione viene eseguita a partire dallo statorisultante dall’esecuzione dell’istruzione che la precede nella sequenza.
I Assegnamento e ingresso sono istruzioni semplici il blocco eun’istruzione composta.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 35
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
SEQUENZA: esempi
Stato iniziale Sequenza Stato Finale{ x 10, y 20} { x = 5; x = x+y; } { x 25, y 20}{ x 10, y 20} { x = x+1; y = x+1; } { x 11, y 12}{ x 10, y 20} { x = x+y; y = x+y; } { x 30, y 50}
I In tutti gli esempi, lo stato finale si ottiene dall’esecuzione delsecondo assegnamento nello stato intermedio risultantedall’esecuzione del primo assegnamento.
I Ad esempio, nel terzo caso:
Stato iniziale Prima istruzione Stato Intermedio{ x 10, y 20} x = x+y; { x 30, y 20}Stato intermedio Seconda istruzione Stato Finale{ x 30, y 20} y = x+y; { x 30, y 50}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 36
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Istruzioni di controllo: CONDIZIONALE
I Permette di determinare l’azione da intraprendere a seconda delverificarsi o meno di una condizione. La notazione utilizzata e laseguente �� ��if (condizione) istruzione1 else istruzione2
dove condizione indica una espressione booleana, e istruzione1istruzione2 sono istruzioni (semplici o composte).
I L’esecuzione del condizionale if (C) S1 else S2 consiste nel
(i) Calcolare il valore, sia esso val, dell’espressione booleana C(ii) Eseguire S1 se val e true, eseguire S2 se val e false.
I Si noti che la presenza dell’istruzione condizionale non e in conflittocon il requisito di non ambiguita degli algoritmi: l’azione daintraprendere e univocamente determinata dal valore di verita dellacondizione e dunque non vi e facolta di scelta da parte dell’esecutore.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 37
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
CONDIZIONALE: esempi
Stato iniziale Condizionale Stato Finaleif (x > y)
z = x ;else z = y ;
{ x 10, y 20} { x 10, y 20, z 20}
{ x 10, y 5} { x 10, y 5, z 10}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 38
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Istruzioni di controllo: RIPETIZIONE
I Consente di ripetere l’esecuzione di una istruzione (o sequenza diistruzioni) fino al verificarsi di una certa condizione (cfr. esempio delcalcolo del prodotto tra due numeri).�� ��while (condizione) Istruzione
dove condizione indica una espressione booleana.
I Terminologia: in while (C) S , la condizione C e detta guardia el’struzione S e detta corpo (del ciclo).
I L’esecuzione di while (C) S consiste nel
(i) Calcolare il valore, sia esso val, dell’espressione booleana C(ii) Se val e false, terminare l’esecuzione.(iii) Se val e true, eseguire S e ripetere dal punto (i).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 39
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
RIPETIZIONEEsempio: Riformulazione del passo 4 dell’algoritmo per il prodotto(versione 2):
while (b>0){
c = c+a;b = b-1;
}I Intuitivamente, l’esecuzione di
while (guardia) corpo
corrisponde all’esecuzione di una sequenza del tipo
{ corpo corpo corpo ... corpo ...}I In tale sequenza, ogni ripetizione dell’istruzione corpo viene detta
iterazione del ciclo.In generale, non e possibile determinare a priori il numero di iterazioni(che puo anche essere 0 nel caso in cui la guardia sia falsa nello statoiniziale).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 40
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
RIPETIZIONE
I L’aspetto piu critico e il fatto che l’esecuzione di un ciclo puo esserefonte di non terminazione dell’esecuzione dell’intero algoritmo.
while (3>0) x = 0;
I Un ciclo siffatto provoca la non terminazione dell’esecuzione, dalmomento che il valore di verita della guardia e sempre true e dunquel’esecuzione corrisponde ad una sequenza infinita
x = 0; x = 0; . . . . . . ; x = 0; . . . . . .
I E compito di chi definisce l’algoritmo assicurare che i cicli presentinon diano luogo a non terminazione.
I La pratica programmativa, ed il buon senso, suggeriscono ad esempiodi utilizzare cicli in cui:
- il valore di verita della guardia dipende dallo stato;- l’esecuzione del corpo comporta modifiche di associazioni nello stato
dalle quali dipende il valore di verita della guardia.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 41
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
RIPETIZIONE
I Le indicazioni appena viste non sono tuttavia sufficienti a garantire laterminazione dell’esecuzione. Si consideri ad esempio il ciclo:
while (x>0) x = x+1;
che soddisfa entrambi i requisiti richiesti, ma che puo non terminarenel caso in cui venga eseguito a partire da uno stato dove il valoreassociato al nome x e un valore positivo.
I A partire dagli anni ’70 sono stati sviluppati dei metodi formali per laverifica di correttezza di programmi, che comprendono tecniche per ladimostrazione formale di proprieta di terminazione dei cicli.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 42
Concetti di base della programmazione Pseudo-linguaggio per la specifica di algoritmi
Istruzioni di controllo: OUTPUT
I Permette di rendere visibile all’esterno la parte desiderata dello stato.La notazione utilizzata e �� ��Output(x);
dove x indica un nome simbolico.I L’esecuzione di questa istruzione consiste nel:
(i) Recuperare il valore, sia esso val, associato nello stato al nomesimbolico x.
(ii) Produrre in uscita tale valore.
I Questa operazione non comporta la modifica dello stato. Neilinguaggi di programmazione reali, l’esecuzione delle operazioni diuscita produce di solito la visualizzazione di valori su supporti fisiciquali video, stampanti etc.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 43
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Problema: Calcolo del valore assoluto di un numero
Vediamo alcuni esempi di specifica di algoritmi che utilizzano lopseudo-linguaggio.
Specifica:Stato iniziale: { numero A }Stato finale: { risultato |A| }
dove A indica un (generico) valore intero.
Algoritmo:
if (numero > 0)risultato = numero;
else risultato = - numero;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 44
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Problema: Ordinare due interi positivi
Specifica:
Stato iniziale: { num1 A, num2 B }Stato finale: { num1 max(A,B), num2 min(A,B) }
Algoritmo:
if (num1 < num2){
temp = num1;num1 = num2;num2 = temp;
}else ;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 45
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Problema: Ordinare due interi positivi (cont.)
I Si noti l’utilizzo di un nome simbolico aggiuntivo (temp): e essenzialeper poter effettuare correttamente lo scambio tra i valori associati aidue interi (a causa del carattere distruttivo dell’assegnamento e dellasequenzialita dell’esecuzione).
I E facile verificare che una sequenza del tipox = y;y = x;
non consente, in generale, di scambiare i valori associati a x e y.
Esempio:
Stato iniziale Stato Intermedio{ x 10, y 20} x = y; { x 20, y 20}
Stato intermedio Stato Finale{ x 20, y 20} y = x { x 20, y 20}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 46
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Problema: Elevamento a potenza
Specifica:
Stato iniziale: { base A, esponente B } con A>0 e B ≥0Stato finale: { risultato AB}
I L’algoritmo si basa sulla seguente, ben nota, definizione dielevamento a potenza.
A0 = 1
AB = A×A× . . .×A︸ ︷︷ ︸ (se B > 0)
B volte
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 47
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Algoritmo:
risultato = 1;while (esponente > 0){
risultato = risultato * base;esponente = esponente - 1;
}I Nell’algoritmo, si assume che i valori iniziali di base ed esponente
soddisfino i requisiti della specifica.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 48
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Input/Output
I Nei problemi visti fino ad ora non ci siamo preoccupati di acquisire idati iniziali ne di produrre in uscita i risultati finali.
Esempio: Ordinare due valori interi acquisiti in input e stampare ivalori ordinati.
Algoritmo:Input(num1);Input(num2);,if num1 < num2{
temp = num1;num1 = num2;num2 = temp;
}else ;Output(num1);Output(num2);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 49
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Problema: Calcolare quoziente e resto della divisione tradue numeri naturali non nulli.
Specifica:Stato iniziale: {x A, y B} con A,B > 0Stato finale: {x A, y B, q Q, r R}
con A = Q · B + R e 0 ≤ R < B
Algoritmo:q = 0;r = x;while (r ≥ y){
q = q + 1;r = r - y;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 50
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Calcolare il MCD con l’algoritmo di Euclide
I Dati due naturali non nulli si calcola il MCD utilizzando le seguentiproprieta:
MCD(x , x) = x
MCD(x , y) = MCD(x − y , y) se x > y
MCD(x , y) = MCD(x , y − x) se y > x
Specifica:Stato iniziale: {x A, y B} con A,B > 0Stato finale: {x MCD(A,B)}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 51
Concetti di base della programmazione Esempi d’uso dello pseudo-linguaggio
Calcolare il MCD con l’algoritmo di Euclide (cont.)
Algoritmo:while (x 6= y){
if (x > y)x = x - y;
elsey = y - x;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 52
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione binaria
I Per informazione intendiamo tutto quello che viene manipolato da uncalcolatore:
I numeri (naturali, interi, reali, . . . )I caratteriI immaginiI suoniI programmiI . . .
I La piu piccola unita di informazione memorizzabile o elaborabile daun calcolatore, il bit, corrisponde allo stato di un dispositivo fisico cheviene interpretato come 1 o 0.
I In un calcolatore tutte le informazioni sono rappresentate in formabinaria, come sequenze di 0 e 1.
I Per motivi tecnologici: distinguere tra due valori di una grandezzafisica e piu semplice che non ad esempio tra dieci valori.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 53
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione di numeri naturali
I Un numero naturale e un oggetto matematico, che puo essererappresentato mediante una sequenza di simboli di un alfabeto fissato.
I E importante distinguere tra numero e sua rappresentazione: ilnumerale “234” e la rappresentazione del numero 234.
I Si distinguono 2 tipi di rappresentazione:
additiva: ad es. le cifre romaneposizionale: una cifra contribuisce con un valore diverso al numero a
seconda della posizione in cui si trova
I Noi consideriamo solo la rappresentazione posizionale.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 54
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione posizionale
I Un numero e rappresentato da una sequenza finita di cifre di un certoalfabeto: �� ��cn−1cn−2 · · · c1c0 = Nb
c0 viene detta cifra meno significativa
cn−1 viene detta cifra piu significativa
I Il numero b di cifre diverse (dimensione dell’alfabeto) e detto base delsistema di numerazione.
I Ad ogni cifra e associato un valore compreso tra 0 e b − 1.
Base Alfabeto Sistema2 0, 1 binario8 0, . . . , 7 ottale10 0, . . . , 9 decimale16 0, . . . , 9, A, . . . , F esadecimale
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 55
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
I Il significato di una sequenza di cifre (il numero N che essarappresenta) dipende dalla base b:
cn−1 · bn−1 + cn−2 · bn−2 + · · ·+ c1 · b1 + c0 · b0 =n−1∑i=0
ci · bi = N
Esempio: Il numerale 101 rappresenta numeri diversi a seconda delsistema usato:
Sistema Base b 101b Valore10
decimale 10 (101)10 101binario 2 (101)2 5ottale 8 (101)8 65esadecimale 16 (101)16 257
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 56
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Intervallo di rappresentazione
I I numeri rappresentabili in base b con n posizioni (cifre) vanno da 0 abn − 1.
3 cifre in base 10 : da 0 a 999 = 103 − 18 cifre in base 2 : da 0 a 255 = 28 − 1
16 cifre in base 2 : da 0 a 65 535 = 216 − 132 cifre in base 2 : da 0 a 4 294 967 296 = 232 − 12 cifre in base 16 : da 0 a 255 = 162 − 18 cifre in base 16 : da 0 a 4 294 967 296 = 168 − 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 57
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Conversioni di base: da base b a base 10
I Usando direttamente
cn−1 · bn−1 + cn−2 · bn−2 + · · ·+ c1 · b1 + c0 · b0 =n−1∑i=0
ci · bi = N
esprimendo le cifre e b in base 10 (e facendo i conti in base 10)
Esercizio(domani) Scrivere l’algoritmo di conversione da base b a base 10.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 58
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Conversioni di base: da base 10 a base bN = c0 + c1 · b1 + c2 · b2 + · · ·+ ck−1 · bk−1
= c0 + b · (c1 + b · (c2 + · · ·+ b · ck−1) · · · )
I Vogliamo determinare le cifre c0, c1, . . . , ck−1
I Consideriamo la divisione di N per b:
N = R + b · Q (0 ≤ R < b)
= c0 + b · (c1 + b · (· · · ))⇓
R = c0 ovvero, il resto R della divisione di N per b da
c0 (cifra meno significativa)
Q = c1 + b · (· · · )
I A partire dal quoziente Q si puo iterare il procedimento per ottenerele cifre successive (fino a che Q diventa 0).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 59
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Conversione da base 10 a base bi = 0;while (num ! = 0) {
c[i] = num % b;num = num / b;i = i+1; }
N.B. Le cifre vengono determinate dalla meno significativa alla piusignificativa.Esempio: (25)10 = (???)2 = (11001)2
N : b Q R cifra25 : 2 12 1 c0
12 : 2 6 0 c1
6 : 2 3 0 c2
3 : 2 1 1 c3
1 : 2 0 1 c4
N.B. servono 5 bit (con cui possiamo rappresentare i numeri da 0 a 31)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 60
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione di numeri interi
I Dobbiamo rappresentare anche il segno: si usa uno dei bit (quello piusignificativo)
Rappresentazione tramite modulo e segno
I il bit piu significativo rappresenta il segno
I le altre n − 1 cifre rappresentano il valore assolutoI problemi:
I doppia rappresentazione per lo zero (00 · · · 00 e 10 · · · 00)I le operazioni aritmetiche sono complicate (analisi per casi)
=⇒ invece della rappresentazione tramite modulo e segno si usa unarappresentazione in complemento alla base
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 61
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione in complemento alla base
In quanto segue b indica la base e n indica il numero complessivo di cifre.
I Con base b e n cifre, abbiamo a disposizione bn configurazionidistinte.
I Utilizziamo meta delle configurazioni per rappresentare numeripositivi e l’altra meta per rappresentare numeri negativi.
||X || =
{X se X ≥ 0
bn − |X | se X < 0
I in questo modo si rappresentano gli interi relativi nell’intervallo[−bn/2, bn/2)
I se X ≥ 0: ||X || e compresa in [0, bn/2)I se X < 0: ||X || e compresa in [bn/2, bn)
I lo 0 ha una sola rappresentazione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 62
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione in complemento alla baseN b = 10 e n = 1 b = 2 e n = 3
−5 5−4 6 100−3 7 101−2 8 110−1 9 1110 0 0001 1 0012 2 0103 3 0114 4
I se b = 2 =⇒ rappresentazione in complemento a 2I rappresentazione degli interi relativi nell’intervallo [−2n−1, 2n−1)I positivi: la cifra piu significativa e 0 (rappresentati nella parte inferiore
dell’intervallo)I negativi: la cifra piu significativa e 1 (rappresentati nella parte
superiore dell’intervallo)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 63
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazione di complementazione
Vogliamo determinare un algoritmo per determinare la rappresentazione incomplemento alla base di −X , data quella di X . Indipendentemente dalsegno di X , abbiamo:
||X ||+ || − X || = |X |+ bn − |X | = bn
per cui|| − X || = bn − ||X ||
o equivalentemente|| − X || = bn − 1− ||X ||+ 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 64
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazione di complementazioneI Supponiamo:
||X || =n−1∑i=0
ci · bi
e ricordiamo che la rappresentazione di bn − 1 e
n−1∑i=0
(b − 1) · bi
I Otteniamo:
|| − X || = bn − 1− ||X ||+ 1
= (n−1∑i=0
(b − 1) · bi )− (n−1∑i=0
ci · bi ) + 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 65
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazione di complementazioneI Sia ora k la prima posizione significativa di ||X ||, ovvero la prima cifra (a
partire da destra) diversa da 0. Abbiamo allora:
|| − X || = (n−1∑i=0
(b − 1) · bi )− (n−1∑i=0
ci · bi ) + 1
= (n−1∑i=0
(b − 1) · bi )− (n−1∑i=k
ci · bi ) + 1
= (n−1∑
i=k+1
((b − 1)− ci ) · bi ) + ((b − 1)− ck) · bk +
(k−1∑i=0
(b − 1) · bi ) + 1
I Osserviamo ora che (k−1∑i=0
(b − 1) · bi ) + 1 = bk .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 66
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazione di complementazione
I Sia ora k la prima posizione significativa di ||X ||, ovvero la prima cifra (apartire da destra) diversa da 0. Abbiamo allora:
|| − X || = (n−1∑i=0
(b − 1) · bi )− (n−1∑i=0
ci · bi ) + 1
= (n−1∑i=0
(b − 1) · bi )− (n−1∑i=k
ci · bi ) + 1
= (n−1∑
i=k+1
((b − 1)− ci ) · bi ) + ((b − 1)− ck) · bk + bk
I Osserviamo ora che (k−1∑i=0
(b − 1) · bi ) + 1 = bk .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 67
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazione di complementazione
|| − X || = (n−1∑
i=k+1
((b − 1)− ci ) · bi ) + ((b − 1)− ck) · bk + bk
= (n−1∑
i=k+1
((b − 1)− ci ) · bi ) + (b − ck) · bk
I L’ultimo addendo e 0, poiche ci = 0, per ogni i = 0, . . . , k − 1.
I Come possiamo leggere quanto ottenuto?
La rappresentazione di −X si ottiene da quella di X :
1. ricopiando gli zeri meno significativi2. complementando alla base la prima cifra significativa3. complementando alla base meno uno le rimanenti cifre
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 68
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazione di complementazione
|| − X || = (n−1∑
i=k+1
((b − 1)− ci ) · bi ) + ((b − 1)− ck) · bk + bk
= (n−1∑
i=k+1
((b − 1)− ci ) · bi ) + (b − ck) · bk + (k−1∑i=0
ci · bi )
I L’ultimo addendo e 0, poiche ci = 0, per ogni i = 0, . . . , k − 1.
I Come possiamo leggere quanto ottenuto?
La rappresentazione di −X si ottiene da quella di X :
1. ricopiando gli zeri meno significativi2. complementando alla base la prima cifra significativa3. complementando alla base meno uno le rimanenti cifre
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 69
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazione di complementazione
Esempio: b = 3, n = 4, ||X || = 0210 (dunque X = (21)10)
|| − X || = 2020
Verifichiamo:
I 2020 = (60)10
I 34 − 60 = 81− 60 = 21 = | − X |
Nel caso del complemento a 2 abbiamo piu semplicemente:
I si lasciano inalterate tutte le cifre fino al primo 1 compreso
I si invertono le rimanenti cifre
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 70
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Complemento a 2
Esempio: Rappresentazione di −298 in complemento a 2:
I 298 = 256 + 32 + 8 + 2
I ||298|| = 100101010 = 0100101010
I || − 298|| = 1011010110
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 71
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazioni su interi relativi in complemento a 2
Somma di due numeri
I si effettua bit a bit
I non e necessario preoccuparsi dei segni
I il risultato sara corretto (in complemento a 2 se negativo)
I puo verificarsi trabocco (overflow) =⇒ il risultato non e corretto
Si verifica quando il numero di bit a disposizione non e sufficiente perrappresentare il risultato.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 72
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazioni su interi relativi in complemento a 2Esempio: n = 5, ±9± 3, ±9± 8intervallo di rappresentazione: da −24 a 24 − 1 (da −16 a 15)
rip. 00011 11001 00111 11111+9 01001 +9 01001 -9 10111 -9 10111+3 00011 -3 11101 +3 00011 -3 11101+12 01100 +6 00110 -6 11010 -12 10100
In questi casi non si ha trabocco.
rip. 01000 10000+9 01001 -9 10111+8 01000 -8 11000-15 10001 +15 01111(e non +17) (e non −17)
Si ha trabocco quando il riporto sul bit di segno e diverso dall’ultimoriporto.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 73
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Operazioni su interi relativi in complemento a 2
Differenza tra due numeri: si somma al primo il complemento delsecondo
Esempio: n = 5, intervallo di rappresentazione: da −16 a 15
rip. 11111+9 01001-9 101110 00000
11001+9 01001-3 11101+6 00110
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 74
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Numeri frazionariI Numeri reali compresi tra 0 e 1: si rappresentano comunemente come
N = 0.c−1c−2 . . . c−n
I Il peso delle cifre dipende, al solito, dalla loro posizione e dalla baseprescelta
Nb = c−1 · b−1 + c−2 · b−2 + · · ·+ c−n · b−n =−1∑
i=−n
ci · bi
Esempio: Consideriamo b = 10 ed il numero 0.587
0.58710 = 5 · 10−1 + 8 · 10−2 + 7 · 10−3
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 75
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Numeri frazionari
Nb =−1∑
i=−n
ci · bi (•)
I Nel caso di un numero frazionario in binario, possiamo usare la (•)per convertirlo in base 10
Esempio: Convertiamo in base 10 il numero frazionario binario0.10112
0.10112 = 1 · 2−1 + 1 · 2−3 + 1 · 2−4 = 0.687510
I La rappresentazione dei numeri frazionari puo introdurreapprossimazioni dovute alla limitatezza delle cifre dopo la virgola.
I L’approssimazione e comunque inferiore a b−n dove n e il numero dicifre utilizzate.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 76
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Conversione di un numero frazionario da base 10 a base 2
I Il metodo piu semplice consiste nell’effettuare una sequenza dimoltiplicazioni per 2 prendendo ad ogni passo la parte intera delrisultato come cifra binaria della rappresentazione
I Esempio: Convertiamo 0.125 in base 2
0.125 × 2 = 0.25 00.25 × 2 = 0.5 00.5 × 2 = 1.0 1
I In questo caso abbiamo una rappresentazione esatta su 3 cifre(0.125 = 1/8)
0.12510 = 0.0012
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 77
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Conversione di un numero frazionario da base 10 a base 2
I Esempio: Convertiamo 0.58710 in base 2
0.587 × 2 = 1.174 10.174 × 2 = 0.348 00.348 × 2 = 0.696 00.696 × 2 = 1.392 10.392 × 2 = 0.784 00.784 × 2 = 1.568 10.568 × 2 = . . .
I Quindi la rappresentazione di 0.58710 in base 2 e:I 0.10012 con 4 cifre (approssimazione accurata entro 2−4)I 0.1001012 con 6 cifre (approssimazione accurata entro 2−6)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 78
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
L’aritmetica reale
I L’insieme dei reali (e dei razionali) e infinito =⇒ non e possibilerapprentarlo tutto
Rappresentazione in virgola fissaSi rappresentano separatamente, usando un numero fissato di cifre• parte intera e,• parte frazionaria(si usa una virgola per separare le due parti)
Nb = cn−1 cn−2 · · · c1 c0 , c−1 c−2 · · · c−m
rappresenta il numero
N = cn−1 · bn−1 + · · ·+ c0 · b0 + c−1 · b−1 + · · ·+ c−m · b−m
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 79
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
L’aritmetica realeI Limitazioni della rappresentazione:
I k bit per la parte intera =⇒ (−2k , 2k)I m bit per la parte frazionaria =⇒ precisione ≤ 2−m
Rappresentazione in virgola mobile (floating point)
Utilizza la notazione esponenziale. Si esprime il numero comeprodotto di due parti
X = m · be
Esempio:1150 = 1.15× 103
ma anche
1150 = 0.115× 104
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 80
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione in virgola mobile
Rappresentazione in forma normalizzata in base b
X = m · be
I e e la caratteristica in base b di X : intero relativo
I m e la mantissa in base b di X : numero frazionario tale che1/b ≤ |m| < 1
I Esempio:1150 = 0.115 × 104
mantissa caratteristica
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 81
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione in virgola mobile
I Se la caratteristica e rappresentata dalla sequenza di cifre
c1 c2 c3 · · ·
allora rappresenta il valore
c1 · b−1 + c2b−2 + · · ·
Esempio: X = (5)10 = (101)2 che normalizzato diventa:
m = |m| = (0.101 · · · 0000)2e = (11)2
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 82
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione in virgola mobile
I Fissati:I k bit per mantissaI h bit per caratteristicaI 1 bit per il segno
l’insieme di reali rappresentabili e fissato (e limitato)
(0.1) 1/2 ≤ |m| ≤k∑
i=12−i (0.11 . . . 1)
|e| ≤ 2h−1 − 1
I Questo fissa anche massimo e minimo (in valore assoluto) numerorappresentabile.
I Assunzione realistica: reali rappresentati con 32 bit:I 24 bit per la mantissaI 7 bit per la caratteristica (in complemento)I 1 bit per il segno della mantissa (0 positivo, 1 negativo)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 83
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Rappresentazione in virgola mobile
Insieme F dei numeri rappresentabili in virgola mobile
I sottoinsieme finito dei numeri razionali rappresentabili (con n bit)
I simmetrico rispetto allo 0I gli elementi non sono uniformemente distribuiti sull’asse reale
I densi intorno allo 0I radi intorno al massimo rappresentabile
m1 = 0.10, m2 = 0.11, e1 = 5X1 = 0.10× 105 = 10000X2 = 0.11× 105 = 11000
I molti razionali non appartengono ad F (ed es. 1/3, 1/5, . . . )
I non e chiuso rispetto ad addizioni e moltiplicazioni
I per rappresentare un reale X si sceglie l’elemento di F piu vicino ad X
I la funzione che associa ad un reale X l’elemento di F piu vicino ad Xe detta funzione di arrotondamento
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 84
Rappresentazione dell’informazione (cenni) Rappresentazione informazione
Limitazioni aritmeticheDovute al fatto che il numero di bit usati per rappresentare un numero elimitato
I perdita di precisione
I arrotondamento: mantissa non sufficiente a rappresentare tutte lecifre significative del numero
I errore di overflow: caratteristica non sufficiente (numero troppogrande)
I errore di underflow: numero troppo piccolo viene rappresentato come0
Formati standard proposti da IEEE (Institute of Electrical and ElectronicsEngineers)
I singola precisione: 32 bit
I doppia precisione: 64 bit
I quadrupla precisione: 128 bit
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 85
Sistemi di elaborazione Architettura del calcolatore
Architettura di Von Neumann
I L’architettura e ancora quella classica sviluppata da Von Neumannnel 1947.
I L’architettura di Von Neumann riflette le funzionalita richieste da unelaboratore:
I memorizzare i dati e i programmi =⇒ memoria principaleI i dati devono essere elaborati =⇒ unita di elaborazione (CPU)I comunicazione con l’esterno =⇒ unita di ingresso/uscita (periferiche)I le componenti del sistema devono scambiarsi informazioni =⇒ bus di
sistema
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 86
Sistemi di elaborazione Architettura del calcolatore
Memoria
Secondaria
Memoria
Principale
Unita
di
Ingresso
Unita
di
Uscita
Bus
CPU
Unita periferiche
Tra le periferiche evidenziamo la memoria secondaria.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 87
Sistemi di elaborazione Architettura del calcolatore
Memoria centrale (o RAM)h bit
012...
2k-1
I e una sequenza di celle di memoria (dette parole), tutte della stessadimensione
I ogni cella e costituita da una sequenza di bitI il numero h di bit di una cella di memoria (dimensione) dipende
dall’elaboratore, ed e un multiplo di 8: 8, 16, 32, 64I ogni cella di memoria e identificata in modo univoco dal suo indirizzoI il numero k di bit necessari per l’indirizzo dipende dal numero di celle
di memoriak bit =⇒ 2k celle
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 88
Sistemi di elaborazione Architettura del calcolatore
Memoria centrale
012
2k − 1
972 11001010
k bit
h bit
...
...
h bit
972
CPU
registro
registro
indirizzi (RI)
dati (RD)
bus indirizzi
bus dati11001010
Operazione di lettura:
1. CPU scrive l’indirizzo della cella di memoria da cui leggere nelregistro indirizzi (RI)
2. esegue l’operazione (“apre i circuiti”)
3. il valore della cella indirizzata viene trasferito nel registro dati (RD)
Operazione di scrittura: al contrario
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 89
Sistemi di elaborazione Architettura del calcolatore
Memoria centraleCaratteristiche principali
I e una memoria ad accesso casuale, ossia il tempo di accesso ad unacella di memoria e indipendente dalla posizione della cella =⇒ vienechiamata RAM (random access memory)
I puo essere sia letta che scrittascrittura distruttiva – lettura non distruttiva
I alta velocita di accesso
I e volatile (si perde il contenuto quando si spegne il calcolatore)
Dimensione della memoria: misurata in byte (1 byte=8 bit)
Kilobyte = 210 ∼ 103 byteMegabyte = 220 ∼ 106 byteGigabyte = 230 ∼ 109 byteTerabyte = 240 ∼ 1012 byte
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 90
Sistemi di elaborazione Architettura del calcolatore
Memoria secondaria
I non volatile
I capacita maggiore della memoria centrale (decine di GB)
I tempo di accesso lento rispetto alla memoria centrale
I accesso sequenziale e non casuale
I tipi di memoria secondaria: dischi rigidi, floppy, CDROM, CDRW,DVD, nastri, . . .
Bus di sistema suddiviso in tre parti:
I bus indirizzi: k bit
I bus dati: h bit
I bus comandi: trasferisce i comandi tra le varie unita
=⇒ parallelismo (attualmente si arriva a 128 bit)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 91
Sistemi di elaborazione Architettura del calcolatore
CPU (Central Processing Unit)I coordina le attivita di tutte le componenti del calcolatore
I interpreta ed esegue le istruzioni del programma
I 3 componenti principali:
unita logico-aritmetica (ALU): effettua i calcoli
unita di controllo: coordinamento di tutte le operazioni
registri: celle di memoria ad accesso molto veloceI registro istruzione corrente (IR): contiene l’istruzione in corso di
esecuzioneI contatore di programma (PC): contiene l’indirizzo della prossima
istruzione da eseguireI accumulatori: utilizzati dalla ALU per gli operandi ed il risultatoI registro dei flag: memorizza alcune informazioni sul risultato
dell’ultima operazione (carry, zero, segno, overflow, . . . )I registro interruzioni: utilizzato per la comunicazione con le perifericheI registro indirizzi (RI) e registro dati (RD) per il trasferimento da e
verso la memoria centrale
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 92
Sistemi di elaborazione Architettura del calcolatore
CPU
Ciclo dell’unita di controllo
I Tutte le attivita interne alla CPU sono regolate da un orologio (clock)che genera impulsi regolari ad una certa frequenza (ad es. 800 MHz,1 GHz, 2 GHz, . . . ).
I Il programma e memorizzato in celle di memoria consecutive, sullequali l’unita di controllo lavora eseguendo il ciclo di
prelievo — decodifica — esecuzione
while macchina in funzione dopreleva dalla memoria l’istruzione indirizzata da PCe caricala in IR(aggiorna PC in modo che indirizzi la prossima istruzione)
decodifica l’istruzione in IResegui l’istruzioneendwhile
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 93
Sistemi di elaborazione Architettura del calcolatore
CPU - Ciclo dell’unita di controllo
1. fase di prelievo (fetch)l’unita di controllo acquisisce dalla memoria l’istruzione indirizzata daPC e aggiorna PC in modo che indirizzi la prossima istruzione
PC = PC + ndove n e la lunghezza in byte dell’istruzione prelevata
2. fase di decodificaviene decodificato il tipo di istruzione per determinare quali sono ipassi da eseguire per la sua esecuzione
3. fase di esecuzionevengono attivate le componenti che realizzano l’azione specificata
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 94
Sistemi di elaborazione Architettura del calcolatore
Istruzioni
Ogni istruzione e costituita da:
01001001 00110011
codice operativo operandi
Tipi di istruzioneI istruzioni di trasferimento dati
– da e verso la memoria centrale– ingresso/uscita
I istruzioni logico/aritmeticheI istruzioni di controllo
– istruzioni di salto
Le istruzioni dettano il flusso del programma. Vengono eseguite insequenza, a meno che non vi sia un’istruzione di controllo che alterail normale flusso (istruzione di salto).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 95
Sistemi di elaborazione Dal codice sorgente al codice macchina
Dal codice sorgente al codice macchinaI concetti di algoritmo e di programma permettono di astrarre dalla realestruttura del calcolatore, che comprende sequenze di 0 e 1, ovvero unlinguaggio macchina.Livelli di astrazione ai quali possiamo vedere i programmi:
I Linguaggio macchina (o codice binario): livello piu bassoI un programma e una sequenza di 0 e 1 (suddivisi in parole) che
codificano le istruzioniI dipende dal calcolatore
I Linguaggio assemblativo: livello intermedioI dipende dal calcolatore e le sue istruzioni sono in corrispondenza 1-1
con le istruzioni in linguaggio macchinaI istruzioni espresse in forma simbolica =⇒ comprensibile da un umano
I Linguaggi ad alto livello: (e.g. C, Pascal, C++, Java, Fortran, . . . )I si basano su costrutti non elementari, comprensibili da un umanoI istruzioni piu complesse di quelle eseguibili da un calcolatore
(corrispondono a molte istruzioni in linguaggio macchina)I in larga misura indipendenti dallo specifico elaboratore
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 96
Sistemi di elaborazione Dal codice sorgente al codice macchina
Per arrivare dalla formulazione di un problema all’esecuzione del codiceche lo risolve, bisogna passare attraverso diversi stadi:
problema (specifica)⇓
algoritmo (pseudo-codice)⇓
codice sorgente (linguaggio ad alto livello)⇓ compilazione — [compilatore]
codice oggetto (simile al codice macchina, ma con riferimenti simbolici)⇓ collegamento tra le diverse parti — [collegatore (linker)]
codice macchina (eseguibile)⇓ caricamento — [caricatore (loader)]
codice in memoria eseguito
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 97
Sistemi di elaborazione Dal codice sorgente al codice macchina
Esempio: dati due interi positivi X ed Y, eseguire il loro prodotto usandosolo le operazioni di somma e sottrazioneInput(X);Input(Y);somma = 0;contatore = 0;while (contatore < Y){
somma = somma + X;contatore = contatore + 1;
}Output(somma);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 98
Sistemi di elaborazione Dal codice sorgente al codice macchina
Codifica dell’algoritmo in C
#include <stdio.h>void main (void) {int x, y;int cont = 0;int somma = 0;printf("Introduci due interi da moltiplicare\n");scanf("%d%d", &x, &y);while (cont < y) {
somma = somma + x;cont = cont + 1;
}printf("La somma di %d e %d e’ pari a %d\n", x, y, somma);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 99
Sistemi di elaborazione Dal codice sorgente al codice macchina
Linguaggio assembler
Vediamo per comodita un esempio di linguaggio assembler: (corrisponde1-1 al codice in linguaggio macchina, ma e piu leggibile).
Caricamento dati
LOAD R1 X Carica nel registro R1 (o R2) il dato memorizzato nella cella diLOAD R2 X memoria identificata dal nome simbolico X
LOAD R1 #C Carica nel registro R1 la costante numerica C
Somma e Sottrazione
SUM R1 R2 Somma (sottrae) il contenuto di R2 al contenuto di R1 eSUB R1 R2 memorizza il risultato in R1
Memorizzazione
STORE R1 X Memorizza il contenuto di R1 (R2) nella cella con nome simbolico XSTORE R2 X
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 100
Sistemi di elaborazione Dal codice sorgente al codice macchina
Linguaggio assembler
Controllo
JUMP A La prossima istruzione da eseguire e quella con etichetta A
JUMPZ A Se il contenuto di R1 e uguale a 0, la prossima istruzione daeseguire e quella con etichetta A
STOP Ferma l’esecuzione del programma
Lettura/Scrittura
READ X Legge un dato e lo memorizza nella cella di nome simbolico X
WRITE X Scrive il valore contenuto nella cella di nome simbolico X
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 101
Sistemi di elaborazione Dal codice sorgente al codice macchina
Programma per il prodotto in linguaggio assemblerEtic. Istr. assembler Istruzione C Significato
0 READ X scanf Leggi valore e mettilo nella cella X
1 READ Y scanf Leggi valore e mettilo nella cella Y
2 LOAD R1 #0 cont = 0 Inizializzazione di cont; metti 0 in R13 STORE R1 CONT Metti il valore di R1 in CONT
4 LOAD R1 #0 somma = 0 Inizializzazione di SOMMA; metti 0 in R15 STORE R1 SOMMA Metti il valore di R1 in SOMMA
6 INIZ LOAD R1 CONT se cont=y Esecuzione del test:7 LOAD R2 Y vai a FINE Metti in R1 (R2) il valore di CONT (Y )8 SUB R1 R2 Sottrai R2 (ossia Y ) da R19 JUMPZ FINE Se R1 = 0 (quindi CONT=Y) vai a FINE
10 LOAD R1 SOMMA somma = Metti in R1 il valore di SOMMA11 LOAD R2 X somma + x Metti in R2 il valore di X12 SUM R1 R2 Metti in R1 la somma tra R1 ed R213 STORE R1 SOMMA Metti il valore di R1 in SOMMA
14 LOAD R1 #1 cont = Incremento contatore; metti 1 in R115 LOAD R2 CONT cont + 1 Metti in R2 il valore di CONT16 SUM R1 R2 Metti in R1 la somma tra R1 ed R217 STORE R1 CONT Metti il valore di R1 in CONT
18 JUMP INIZ Salta a INIZ
19 FINE WRITE SOMMA printf Scrive il contenuto di SOMMA
20 STOP Fine dell’esecuzione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 102
Sistemi di elaborazione Dal codice sorgente al codice macchina
Osservazioni sul codice assembler
I ad una istruzione C corrispondono in genere piu istruzioni assembler(e quindi linguaggio macchina)
Esempio: somma = somma + x=⇒ 1. carica il valore di X in un registro
2. carica il valore di SOMMA in un altro registro3. effettua la somma tra i due registri4. memorizza il risultato nella locazione di memoria di SOMMA
I JUMP e JUMPZ interrompono la sequenzialita delle istruzioniI In realta il compilatore (ed il linker) genera linguaggio macchina
I ogni istruzione e codificata come una sequenza di bitI ogni istruzione occupa una (o piu celle di memoria)I istruzione costituita da 2 parti:
codice operativooperandi
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 103
Sistemi di elaborazione Dal codice sorgente al codice macchina
Un esempio di linguaggio macchinaPer semplicita consideriamo istruzioni con al piu un operando (un indirizzodi memoria ind)
Istruzione assembler Codice operativo
LOAD R1 ind 0000LOAD R2 ind 0001STORE R1 ind 0010STORE R2 ind 0011SUM R1 R2 0100SUB R1 R2 0101JUMP ind 0110JUMPZ ind 0111READ ind 1000WRITE ind 1001STOP 1011LOAD R1 #c 1100
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 104
Sistemi di elaborazione Dal codice sorgente al codice macchina
Indirizzo Codice operativo Indirizzo operando Istr. assembler
0 00000 1000 10101 READ X
1 00001 1000 10110 READ Y
2 00010 1100 00000 LOAD R1 #0
3 00011 0010 11000 STORE R1 CONT
4 00100 1100 00000 LOAD R1 #0
5 00101 0010 10111 STORE R1 SOMMA
6 00110 0000 11000 LOAD R1 CONT
7 00111 0001 10110 LOAD R2 Y
8 01000 0101 ----- SUB R1 R2
9 01001 0111 10011 JUMPZ FINE
10 01010 0000 10111 LOAD R1 SOMMA
11 01011 0001 10101 LOAD R2 X
12 01100 0100 ----- SUM R1 R2
13 01101 0010 10111 STORE R1 SOMMA
14 01110 1100 00001 LOAD R1 #1
15 01111 0001 11000 LOAD R2 CONT
16 10000 0100 ----- SUM R1 R2
17 10001 0010 11000 STORE R1 CONT
18 10010 0110 00110 JUMP INIZ
19 10011 1001 10111 WRITE SOMMA
20 10100 1011 ----- STOP
21 10101 X22 10110 Y23 10111 SOMMA24 11000 CONT
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 105
La programmazione nel linguaggio C Primi passi in C
Introduzione al linguaggio C
I Abbiamo gia visto come un programma non sia altro che unalgoritmo codificato in un linguaggio di programmazione.
I Problema: quale linguaggio scegliere per la codifica di un algoritmo?
I Il linguaggio naturale sarebbe facilmente comprensibile ma non eeseguibile da una macchina.
I Il linguaggio macchina che abbiamo brevemente illustrato e eseguibilema di difficile comprensione.
I Due requisiti fondamentali di un qualsiasi linguaggio per ladescrizione di algoritmi:
I deve essere preciso per non lasciare adito a dubbi interpretativiI deve essere sintetico per non rendere difficile la comprensione dei
programmi.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 106
La programmazione nel linguaggio C Primi passi in C
I Il linguaggio naturale e il linguaggio macchina si collocano inposizioni opposte, soddisfacendo uno solo dei requisiti.
I I linguaggi di programmazione ad alto livello sono progettati proprioper colmare tale gap.=⇒ sono linguaggi adatti a codificare algoritmi pur rimanendocomprensibili.
I La fatica di tradurre un programma nel linguaggio macchina eaffidata a particolari programmi, i compilatori, che traduconoprogrammi scritti nel linguaggio di piu alto livello in programmiequivalenti nel linguaggio macchina.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 107
La programmazione nel linguaggio C Primi passi in C
I Vedremo il cosidetto ANSI C (standard del 1989, con successiveaggiunte)
I Il primo programma C: ciao mondo
#include <stdio.h>main()
/* Stampa un messaggio sullo schermo. */{
printf("Ciao mondo!\n");}
I Questo programma stampa sullo schermo una riga di testo:
Ciao mondo!>
I Vediamo in dettaglio ogni riga del programma.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 108
La programmazione nel linguaggio C Primi passi in C
/* Stampa un messaggio sullo schermo. */
I testo racchiuso tra “/*” e “*/” e un commento
I i commenti servono a chi scrive o legge il programma, per renderlopiu comprensibile
I il compilatore ignora i commenti
I attenzione a non dimenticare di chiudere i commenti con */,altrimenti tutto il resto del programma viene ignorato
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 109
La programmazione nel linguaggio C Primi passi in C
main()
I e una parte presente in tutti i programmi C
I le parentesi “(” e “)” dopo main indicano che main e una funzione
I i programmi C sono composti da una o piu funzioni, tra le quali cideve essere la funzione main=⇒ main e una funzione speciale, perche l’esecuzione del programmaincomincia con l’esecuzione di main
I la parentesi “{” apre il corpo della funzione e “}” lo chiudeI la coppia di parentesi e la parte racchiusa da esse costituiscono un
bloccoI il corpo della funzione contiene le istruzioni (e dichiarazioni) che
costituiscono la funzione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 110
La programmazione nel linguaggio C Primi passi in C
printf("Ciao mondo!\n");I e un’istruzione semplice (ordina al computer di eseguire un’azione)
in questo caso visualizzare (stampare) sullo schermo la sequenza dicaratteri tra apici
I ogni istruzione semplice deve terminare con “;”
I oltre alle istruzioni semplici, esistono anche istruzioni composte (chenon devono necessariamente terminare con “;”)
I la parte racchiusa in una coppia di doppi apici e una stringa (dicaratteri)
I “\n” non viene visualizzato sullo schermo, ma provoca la stampa diun carattere di fine riga
I “\” e un carattere di escape e, insieme al carattere che lo segue,assume un significato particolare (sequenza di escape)
I in realta anche printf e una funzione, e l’istruzione di sopra eun’attivazione di funzione (le vedremo piu avanti)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 111
La programmazione nel linguaggio C Primi passi in C
#include <stdio.h>
I e una direttiva di compilazione
I viene interpretata dal compilatore durante la compilazione
I la direttiva “#include” dice al compilatore di includere il contenutodi un file nel punto corrente
I <stdio.h> e un file che contiene i riferimenti alla libreria standard diinput/output (dove e definita la funzione printf)
I il linguaggio C non prevede istruzioni esplicite di input/output.Queste operazioni sono definite tramite funzioni nella libreriastandard di input/output.
Note:
I e importante distinguere i caratteri maiuscoli da quelli miniscoliMain, MAIN, Printf, PRINTF non andrebbero bene
I si e usata l’indentazione per mettere in evidenza la struttura delprogramma )
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 112
La programmazione nel linguaggio C Primi passi in C
Alcune varianti del programma
#include <stdio.h>main()
/* Stampa un messaggio sullo schermo. */{
printf("Ciao");printf(" mondo!\n");
}
I produce lo stesso effetto del programma precedenteI la seconda invocazione di printf incomincia a stampare dal punto in
cui aveva smesso la primaI Cosa viene stampato se usiamo
printf("Ciao"); printf("Ciao\n");printf("mondo!\n"); printf("mondo!\n");
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 113
La programmazione nel linguaggio C Primi passi in C
Un altro programma: area di un rettangolo
#include <stdio.h>
main() {
int base;
int altezza;
int area;
base = 3;
altezza = 4;
area = base * altezza;
printf("Area: %d\n", area);
}
Quando viene eseguito stampa:
Area: 12>
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 114
La programmazione nel linguaggio C Primi passi in C
Le variabili
Servono a rappresentare, nei programmi, le associazioni (modificabili) dellostato=⇒ cf. x val nello pseudo-linguaggio
Una variabile e caratterizzata dalle seguenti proprieta:
1. nome: serve a identificarla — esempio: area2. valore: valore associato nello stato corrente — Esempio: 4 (puo
cambiare durante l’esecuzione)3. tipo: specifica l’insieme dei possibili valori — Esempio: int (numeri
interi)4. indirizzo: della cella di memoria a partire dal quale e memorizzato il
valore.
Nome, tipo e indirizzo non possono cambiare durante l’esecuzione.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 115
La programmazione nel linguaggio C Primi passi in C
Le variabili (cont.)I Il nome di una variabile e un identificatore C
=⇒ sequenza di lettere, cifre, e che inizia con una lettera o conEsempio: Numero elementi, x1, ma non 1 posto
I puo avere lunghezza qualsiasi, ma solo i primi 31 caratteri sonosignificativi
I lettere minuscole e maiuscole sono considerate distinteI Ad ogni variabile e associata una cella di memoria o piu celle
consecutive, a seconda del suo tipo. Il suo indirizzo e quello dellaprima cella.
I Analogia con una scatola di scarpe etichettata in uno scaffaleI nome =⇒ etichettaI valore =⇒ scarpa che c’e nella scatolaI tipo =⇒ capienza (che tipo di scarpe ci metto dentro)I indirizzo =⇒ posizione nello scaffale (la scatola e incollata)
N.B.I non tutte le variabili sono denotate da un identificatoreI non tutti gli identificatori sono identificatori di variabile (ad es.
funzioni, tipi, parole riservate, . . . )
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 116
La programmazione nel linguaggio C Primi passi in C
Area del rettangolo
I int base; — e una dichiarazione di variabileI viene creata la scatola e incollata allo scaffaleI ha tipo int =⇒ puo contenere interiI ha nome baseI ha un indirizzo (posizione nello scaffale), che e quello della cella di
memoria associata alla variabileI ha un valore iniziale, che pero non e significativo (e casuale)
=⇒ la scatola viene creata piena, pero con una scarpa scelta a caso,ovvero=⇒ l’associazione nello stato e del tipo nome ?
I int altezza;int area;=⇒ come per base
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 117
La programmazione nel linguaggio C Primi passi in C
Variabili numeriche
Variabili intereI per dichiarare variabili intere si puo usare il tipo intI i valori di tipo int sono rappresentati in C con almeno 16 bitI il numero effettivo di bit dipende dal compilatore
Esempio: 32 bit per il compilatore gcc (usato in ambiente Unix)I in C esistono altri tipi per variabili intere (short, long) — li vedremo
piu avanti
Variabili realiI per dichiarare variabili reali si puo usare il tipo float
Esempio: float temperatura;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 118
La programmazione nel linguaggio C Primi passi in C
Area del rettangolo
base = 3;e un’istruzione di assegnamento (come nel nostro pseudo-linguaggio)
I in C l’operatore di assegnamento e denotato dal simbolo “=”I come gia sappiamo, l’effetto e di modificare una associazione nello
stato=⇒ in questo caso il valore 3 viene associato a base, come?=⇒ il nuovo valore viene scritto nella spazio associato alla variabile
I a questo punto la variabile base ha un valore significativo=⇒ da base ? a base 3
altezza = 4; =⇒ come sopra
area = base * altezza;a destra di “=” possono comparire espressioni =⇒ il valore assegnato equello dell’espressione calcolata nello stato corrente
I una variabile all’interno di una espressione sta per il valore ad essaassociato in quel momento (cf. pseudo-linguaggio)
Nota: operatori aritmetici tra interi del C +, -, *, /, %, . . .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 119
La programmazione nel linguaggio C Primi passi in C
Area del rettangolo
printf("Area: %d\n", area);
I e un’istruzione di stampa
I il primo argomento e la stringa di formato che puo contenerespecificatori di formato
I lo specificatore di formato %d indica che deve essere stampato unintero in notazione decimale (d per decimal)
I ad ogni specificatore di formato nella stringa deve corrispondere unvalore che deve seguire la stringa di formato tra gli argomenti diprintf
Esempio: printf("%d%d· · · %d", i1, i2, ..., in);
I nel caso di printf("Ciao mondo!\n"); la stringa di formato nonconteneva specificatori e quindi non vi erano altri argomenti.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 120
La programmazione nel linguaggio C Struttura programmi C
Struttura dei programmi CI Nel semplice programma che abbiamo appena analizzato possiamo
gia vedere la struttura generale di un programma C.
/* DIRETTIVE DI COMPILAZIONE */#include <stdio.h>main() {
/* PARTE DICHIARATIVA */int base;int altezza;int area;
/* PARTE ESECUTIVA */base = 3;altezza = 4;area = base * altezza;printf("Area: %d\n", area);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 121
La programmazione nel linguaggio C Struttura programmi C
Un programma C deve contenere nell’ordine:
I Una parte contenente direttive per il compilatore. Nel nostroprogramma la direttiva
#include <stdio.h>
I l’identificatore predefinito main seguito dalle parentesi ().
I due parti racchiuse tra parentesi graffe
I la parte dichiarativa. Nell’esempio:
int base;
int altezza;
int area;
I la parte esecutiva. Nell’esempio:
base = 3;
altezza = 4;
area = base * altezza;
printf("Area: %d\n", area);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 122
La programmazione nel linguaggio C Struttura programmi C
La parte dichiarativaI E posta prima della codifica dell’algoritmo e obbliga il programmatore
a dichiarare i nomi simbolici che saranno presenti nello stato e di cuifara uso nella parte esecutiva. Contiene i seguenti elementi:
I la sezione delle dichiarazioni di variabili;I la sezione delle dichiarazioni di costanti.
I Le dichiarazioni:I rendono piu pesante la fase di costruzione dei programmi, maI consentono di individuare e segnalare errori in fase di compilazione.
Esempio:int x;int alfa;alfa = 0;x=alfa;alba=alfa+1;
I Nell’ultima linea abbiamo erroneamente scambiato una b con una f=⇒ il compilatore individua alba come variabile non dichiarata.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 123
La programmazione nel linguaggio C Struttura programmi C
Dichiarazioni di variabiliI Abbiamo gia visto esempi di dichiarazioni di variabili.
float x;int base;int altezza;
I Ad ogni variabile viene attribuito, al momento della dichiarazione, untipo=⇒ specifica l’insieme dei valori che la variabile puo assumere
I La dichiarazione puo anche attribuire un valore iniziale alla variabile(inizializzazione)
int x = 0;
I Variabili dello stesso tipo possono essere dichiaratecontemporaneamente
int base, altezza, area;(ma inizializzate singolarmente)
Esempio: int x, y, z=0; solo z e inizializzata a 0.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 124
La programmazione nel linguaggio C Struttura programmi C
Dichiarazioni di costanti (variabili read-only)
I Una dichiarazione di costante crea un’associazione non modificabile=⇒ associa in modo permanente un valore ad un identificatore.
Esempio:const float PiGreco=3.14;const int N=100;
I L’associazione tra il nome PiGreco ed il valore 3.14 non puo esseremodificata durante l’esecuzione.
I Come per le dichiarazioni di variabili, piu costanti dello stesso tipopossono essere dichiarate insieme
Esempio:const float PiGreco=3.14, e=2.718;const int N=100, M=200;
I N.B. cosa succede quando si modifica una variabile read-only non especificato dallo standard ANSI C, dipende dal compilatore.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 125
La programmazione nel linguaggio C Struttura programmi C
Uso di costanti
I Con la dichiarazione const float PiGreco=3.14;l’istruzioneAreaCerchio=PiGreco*RaggioCerchio*RaggioCerchio;
e equivalente aAreaCerchio=3.14*RaggioCerchio*RaggioCerchio
I Maggiore leggibilita dei programmi, dovuta all’uso di nomi simbolici
I Maggiore adattabilita dei programmi che usano costanti
Esempio:Per aumentare la precisione, basta cambiare la dichiarazione inconst float PiGreco = 3.1415;
Senza l’uso della costante si dovrebbero rimpiazzare nel codice tuttele occorrenze di 3.14 in 3.1415 . . .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 126
La programmazione nel linguaggio C Struttura programmi C
Area di un rettangolo di dimensioni lette da tastiera
#include <stdio.h>
main(){int base, altezza, area;
printf("Immetti base del rettangolo e premi INVIO\n");scanf("%d", &base);printf("Immetti altezza del rettangolo e premi INVIO\n");scanf("%d", &altezza);
area = base * altezza;
printf("Area: %d\n", area);}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 127
La programmazione nel linguaggio C Struttura programmi C
Nuova istruzione: scanf("%d", &base);
I scanf e la funzione duale di printf
I legge da input (tastiera) un valore intero e lo assegna alla variabilebase
I "%d" e la stringa di controllo del formato (in questo caso viene lettoun intero in formato decimale)
I “&” e l’operatore di indirizzoI &base indica (l’indirizzo del)la locazione di memoria associata a baseI scanf memorizza in tale locazione il valore letto
I quando viene eseguita scanf il programma si mette in attesa chel’utente immetta un valore. Quando l’utente digita Invio
1. la sequenza di caratteri immessa viene convertita in un intero (formato%d) e
2. l’intero ottenuto viene assegnato alla variabile base (viene cioe scrittonella/e cella/e di memoria a partire dall’indirizzo passato a scanf)
N.B. il precedente valore della variabile base va perduto (cf. Input(base)
nell pseudo-linguaggio.)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 128
La programmazione nel linguaggio C Struttura programmi C
Esempio di esecuzione
I Vediamo cosa avviene durante l’esecuzione (indichiamo in rosso cioche l’utente digita e in particolare con ←↩ il tasto Invio).
Immetti base del rettangolo e premi INVIO5←↩Immetti altezza del rettangolo e premi INVIO4←↩Area: 20
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 129
La programmazione nel linguaggio C Assegnamento
Assegnamento
I Ricordiamo che l’esecuzione di x = exp corrisponde a:
1. valutare il valore dell’espressione exp a destra di “=” (usando i valoricorrenti delle variabili);
2. assegnare poi tale valore alla variabile x a sinistra di “=”.
Esempio:somma = 5;a = 2;somma = somma + a;
......
somma 5 =⇒ 7a 2 2
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 130
La programmazione nel linguaggio C Assegnamento
Esempio:a b
int a, b; ? ?a = 2; 2 ?b = 3; 2 3a = b; 3 3a = a + b; 6 3b = a + b; 6 9
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 131
La programmazione nel linguaggio C Assegnamento
Osservazioni sull’assegnamento
I Attenzione: A sinistra di “=” ci deve essere un identificatore divariabile
=⇒ denota la corrispondente associazione modificabile nello stato.
Esempio: Quali istruzioni sono corrette e quali no?a = a; SI corretta (anche se poco significativa . . . )
a = 2 * a; SI corretta (il valore associato ad a viene raddoppiato)
5 = a; NO, 5 non denota una associazione
modificabile nello stato ma un valore costante
a + b = c; NO, a+b e un’espressione, non una variabile!
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 132
La programmazione nel linguaggio C Tipi di dato semplici
Tipi di dato semplici
I Abbiamo visto nei primi esempi che il C tratta vari tipi di dato=⇒ le dichiarazioni associano variabili e costanti al corrispondentetipo
I Per tipo di dato si intende un insieme di valori e un insieme dioperazioni che possono essere applicate ad essi.
Esempio:I numeri interi {..., -2, -1, 0, 1, 2, ...} e le usualioperazioni aritmetiche (somma, sottrazione, . . . )
I Ogni tipo di dato ha una propria rappresentazione in memoria(codifica binaria) che utilizza un certo numero di celle di memoria.
I Il meccanismo dei tipi ci consente di trattare le informazioni inmaniera astratta, cioe prescindendo dalla sua rappresentazioneconcreta.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 133
La programmazione nel linguaggio C Tipi di dato semplici
L’uso di variabili con tipo ha importanti conseguenze quali:
I per ogni variabile e possibile determinare a priori l’insieme dei valoriammissibili e l’insieme delle operazioni ad essa applicabili
I per ogni variabile e possibile determinare a priori la quantita dimemoria necessaria per la sua rappresentazione
I e possibile rilevare a priori (a tempo di compilazione) errori nell’usodelle variabili all’interno di operazioni non lecite per il tipocorrispondente
Esempio: Nell’espressione y + 3 se la variabile y non e statadichiarata di tipo numerico si ha un errore (almeno dal punto di vistaconcettuale) rilevabile a tempo di compilazione (cioe senza eseguire ilprogramma).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 134
La programmazione nel linguaggio C Tipi di dato semplici
Classificazione dei tipi
I Tipi semplici: consentono di rappresentare informazioni sempliciEsempio: una temperatura, una misura, una velocita, ecc.
I Tipi strutturati: consentono di rappresentare informazioni costituitedall’aggregazione di varie componentiEsempio: una data, una matrice, una fattura, ecc.
I Un valore di un tipo semplice e logicamente indivisibile, mentre unvalore di un tipo strutturato puo essere scomposto nei valori delle suecomponentiEsempio: un valore di tipo data e costituito da tre valori (semplici)
I Il C mette a disposizione un insieme di tipi predefiniti (tipi built-in) edei meccanismi per definire nuovi tipi (tipi user-defined)
Nota: con T identificatore di tipo, nel seguito indichiamo consizeof(T) lo spazio (in byte) necessario per la memorizzazione divalori di tipo T (vedremo che sizeof e una funzione C).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 135
La programmazione nel linguaggio C Tipi di dato semplici
Tipi semplici built-in
I interi
I reali
I caratteri
Per ciascun tipo consideriamo i seguenti aspetti:
1. intervallo di definizione (se applicabile)
2. notazione (sintassi) per le costanti
3. operatori
4. predicati (operatori di confronto)
5. formati di ingresso/uscita
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 136
La programmazione nel linguaggio C Tipi di dato semplici
Tipi interi: interi con segno
I 3 tipi:shortintlong
I Intervallo di definizione: da −2n−1 a 2n−1−1, dove n dipende dalcompilatore
I Vale: sizeof(short) ≤ sizeof(int) ≤ sizeof(long)sizeof(short) ≥ 2 (ovvero, almeno 16 bit)sizeof(long) ≥ 4 (ovvero, almeno 32 bit)
I Compilatore gcc: short: 16 bit, int: 32 bit, long: 32bit
I I valori limite sono contenuti nel file limits.h, che definisce le costanti:SHRT MIN, SHRT MAX, INT MIN, INT MAX, LONG MIN,LONG MAX
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 137
La programmazione nel linguaggio C Tipi di dato semplici
Notazione per le costanti: in decimale: 0, 10, -10, . . .
I Per distinguere long (solo nel codice): 10L (oppure 10l, ma lsembra 1).
Operatori: +, -, *, /, %, ==, !=, <, >, <=, >=
N.B.: l’operatore di uguaglianza si rappresenta con == (mentre = eutilizzato per il comando di assegnamento!)
Ingresso/uscita: tramite printf e scanf, con i seguentispecificatori di formato (dove d indica “decimale”):%hd per short%d per int%ld per long (con l minuscola)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 138
La programmazione nel linguaggio C Tipi di dato semplici
Tipi interi: interi senza segno
I 3 tipi:unsigned shortunsigned intunsigned long
I Intervallo di definizione: da 0 a 2n-1, dove n dipende dalcompilatore.Il numero n di bit e lo stesso dei corrispondenti interi con segno.
I Le costanti definite in limits.h sono:USHRT MAX, UINT MAX, ULONG MAX (n.b. il minimo e sempre 0)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 139
La programmazione nel linguaggio C Tipi di dato semplici
Notazione per le costanti:I decimale: come per interi con segnoI esadecimale: 0xA, 0x2F4B, . . .I ottale: 012, 027513, . . .
I Nel codice si possono far seguire le cifre del numero dallospecificatore u (ad esempio 10u).
Ingresso/uscita: tramite printf e scanf, con i seguentispecificatori di formato:
%u per numeri in decimale%o per numeri in ottale%x per numeri in esadecimale con cifre 0, . . . , 9, a, . . . , f%X per numeri in esadecimale con cifre 0, . . . , 9, A, . . . , F
Per interi short si antepone hlong si antepone l (minuscola)
Operatori: tutte le operazioni vengono fatte modulo 2n.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 140
La programmazione nel linguaggio C Tipi di dato semplici
Caratteri
I Servono per rappresentare caratteri alfanumerici attraverso opportunicodici, tipicamente il codice ASCII (American Standard Code forInformation Interchange).
I Un codice associa ad ogni carattere un intero:Esempio: Codice ASCII:
carattere: ’0’ · · · ’9’ ’:’ ’;’ ’<’intero (in decimale): 48 · · · 57 58 59 60
carattere: ’a’ · · · ’z’ ’{’ ’|’ ’}’intero (in decimale): 97 · · · 122 123 124 125
carattere: ’A’ · · · ’Z’ ’[’ ’\’ ’]’intero (in decimale): 65 · · · 90 91 92 93
I In C i caratteri possono essere usati come gli interi (un caratterecoincide con il codice che lo rappresenta).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 141
La programmazione nel linguaggio C Tipi di dato semplici
Intervallo di definizione: dipende dal compilatore
I Vale: sizeof(char) ≤ sizeof(int)Tipicamente i caratteri sono rappresentati con 8 bit.
Operatori: sono gli stessi di int (operazioni effettuate utilizzando ilcodice del carattere).
Costanti: ’A’, ’#’, . . .
Esempio:char x, y, z;x = ’A’;y = ’\n’;z = ’#’;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 142
La programmazione nel linguaggio C Tipi di dato semplici
I Confrontiamo:char x, y, z; char x, y, z;x = ’A’; x = 65; /* codice ASCII di ’A’ */
y = ’\n’; y = 10; /* codice ASCII di ’\n’ */
z = ’#’; z = 35; /* codice ASCII di ’#’ */
I Non e sbagliato, pero e pessimo stile di programmazione.
I Non e detto che il codice dei caratteri sia quello ASCII.=⇒ Il programma non sarebbe portabile.
Ingresso/uscita: tramite printf e scanf, con specificatore diformato %c
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 143
La programmazione nel linguaggio C Tipi di dato semplici
Attenzione: in ingresso non vengono saltati gli spazi bianchi e gli a capo
Esempio:
int i, j;printf("Immetti due interi\n");scanf("%d%d", &i, &j);printf("%d %d\n", i, j);
Immetti due interi> 18 25←↩18 25
‘
int i, j;char c;printf("Immetti due interi\n");scanf("%d%c%d", &i, &c, &j);printf("%d %d %d\n", i, c, j);
Immetti due interi> 18 25←↩18 32 25
I 32 e il codice ASCII del carattere ’ ’ (spazio)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 144
La programmazione nel linguaggio C Tipi di dato semplici
I Funzioni per la stampa e la lettura di un singolo carattere:
putchar(c); . . . stampa il carattere memorizzato in c
c = getchar(); . . . legge un carattere e lo assegna alla variabile c
Esempio:char c;putchar(’A’);putchar(’\n’);c = getchar();putchar(c);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 145
La programmazione nel linguaggio C Tipi di dato semplici
Tipi reali
I reali vengono rappresentati in virgola mobile (floating point).
I 3 tipi:floatdoublelong double
I Intervallo di definizione:sizeof cifre significative min esp. max esp.
float 4 6 −37 38double 8 15 −307 308long double 12 18 −4931 4932
I Le grandezze precedenti dipendono dal compilatore e sono definite nelfile float.h.
I Deve comunque valere la relazione:sizeof(float) ≤ sizeof(double) ≤ sizeof(long double)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 146
La programmazione nel linguaggio C Tipi di dato semplici
Costanti: con punto decimale o notazione esponenziale
Esempio:double x, y, z, w;x = 123.45;y = 0.0034; /* oppure y = .0034 */z = 34.5e+20; /* oppure z = 34.5E+20 */w = 5.3e-12;
I Nei programmi, per denotare una costante di tipoI float, si puo aggiungere f o F finale
Esempio: float x = 2.3e5f;I long double, si puo aggiungere L o l finale
Esempio: long double x = 2.34567e520L;
Operatori: come per gli interi (tranne “%”)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 147
La programmazione nel linguaggio C Tipi di dato semplici
Ingresso/uscita: tramite printf e scanf, con diversi specificatoridi formato
Output con printf (per float):
I %f . . . notazione in virgola fissa%8.3f . . . 8 cifre complessive, di cui 3 cifre decimali
Esempio:float x = 123.45;printf("|%f| |%8.3f| |%-8.3f|\n", x, x, x);
|123.449997| | 123.450| |123.450 |
I %e (oppure %E) . . . notazione esponenziale%10.3e . . . 10 cifre complessive, di cui 3 cifre decimali
Esempio:double x = 123.45;printf("|%e| |%10.3e| |%-10.3e|\n", x, x, x);
|1.234500e+02| | 1.234e+02| |1.234e+02 |
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 148
La programmazione nel linguaggio C Tipi di dato semplici
Input con scanf (per float):si puo usare indifferentemente %f o %e.
Riassunto degli specificatori di formato per i tipi reali:
float double long double
printf %f, %e %f, %e %Lf, %Le
scanf %f, %e %lf, %le %Lf, %Le
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 149
La programmazione nel linguaggio C Conversioni di tipo
Conversioni di tipo
Situazioni in cui si hanno conversioni di tipo
I quando in un’espressione compaiono operandi di tipo diverso
I durante un’assegnamento x = y, quando il tipo di y e diverso daquello di x
I esplicitamente, tramite l’operatore di cast
I nel passaggio dei parametri a funzione (piu avanti)
I attraverso il valore di ritorno di una funzione (piu avanti)
Una conversione puo o meno coinvolgere un cambiamento nellarappresentazione del valore.
da short a long (dimensioni diverse)da int a float (anche se stessa dimensione)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 150
La programmazione nel linguaggio C Conversioni di tipo
Conversioni implicite tra operandi di tipo diverso nelleespressioni
Quando un’espressione del tipo x op y coinvolge operandi di tipodiverso, avviene una conversione implicita secondo le seguenti regole:
1. ogni valore di tipo char o short viene convertito in int2. se dopo il passo 1. l’espressione e ancora eterogenea si converte
l’operando di tipo inferiore facendolo divenire di tipo superiore secondola seguente gerarchia:
int → long → float → double → long double
Esempio: int x; double y;Nel calcolo di (x+y):
1. x viene convertito in double2. viene effettuata la somma tra valori di tipo double3. il risultato e di tipo double
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 151
La programmazione nel linguaggio C Conversioni di tipo
Conversioni nell’ assegnamento
Si ha in x = exp quando i tipi di x e exp non coincidono.
I La conversione avviene sempre a favore del tipo della variabile asinistra:
se si tratta di una promozione non si ha perdita di informazione
se si ha una retrocessione si puo avere perdita di informazione
Esempio:int i;float x = 2.3, y = 4.5;i = x + y;printf("%d", i); /* stampa 6 */
I Se la conversione non e possibile si ha errore.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 152
La programmazione nel linguaggio C Conversioni di tipo
Conversioni esplicite (operatore di cast)
Sintassi: (tipo) espressione
I Converte il valore di espressione nel corrispondente valore del tipospecificato.
Esempio:
int somma, n;float media;...media = somma / n; /* divisione tra interi */media = (float)somma / n; /* divisione tra reali */
I L’operatore di cast “(tipo)” ha precedenza piu alta degli operatoribinari e associa da destra a sinistra. Dunque(float) somma / nequivale a((float) somma) / n
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 153
La programmazione nel linguaggio C Input/Output
Input/output
I Come gia detto, input e output non sono parte integrante del C
I L’interazione con l’ambiente e demandato alla libreria standard=⇒ un insieme di funzioni a uso dei programmi C
I La libreria stdio.h implementa un semplice modello di ingresso euscita di dati testuali
I un testo e trattato come un successione (stream) di caratteri, ovvero
=⇒ una sequenza di caratteri organizzata in righe, ciascunaterminata da “\n”
I al momento dell’esecuzione, al programma vengono connessiautomaticamente 3 stream:
I standard input: di solito la tastieraI standard output: di solito lo schermoI standard error: di solito lo schermo
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 154
La programmazione nel linguaggio C Input/Output
Input/output (cont.)I Compito della libreria e fare in modo che tutto il trattamento dei dati
in ingresso e uscita si conformi a questo modello
=⇒ il programmatore non si deve preoccupare di come cio siaeffettivamente realizzato
I Ogni volta che si effettua una operazione di lettura attraversogetchar viene acquisito il prossimo carattere dallo standard input eviene restituito il suo valore
(analogamente per scanf che comporta l’acquisizione di uno o piucaratteri a seconda delle specifiche di formato presenti . . . )
I Ogni volta che si effettua una operazione di scrittura (attraversoputchar o printf) tutti i valori coinvolti vengono convertiti insequenze di caratteri e quest’ultime vengo accodate allo standardoutput.
I Tipicamente il sistema operativo consente di redirigere gli streamstandard, ad esempio su uno o piu file.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 155
La programmazione nel linguaggio C Input/Output
Formattazione dell’output con printf
I Riepilogo specificatori di formato principali:I interi: %d, %o, %u, %x, %X
per short: si antepone hper long: si antepone l (minuscola)
I reali: %e, %f, %gper double: non si antepone nullaper long double: si antepone L
I caratteri: %cI stringhe: %s (le vedremo piu avanti)I puntatori: %p (li vedremo piu avanti)
I Flag: messi subito dopo il “%”I “-”: allinea a sinistraI altri flag (non ci interessano)
I Sequenze di escape: \%, \’, \", \\, \a, \b, \n, \t, . . .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 156
La programmazione nel linguaggio C Input/Output
Formattazione dell’input con scanf
I Specificatori di formato: come per l’output, tranne che per i realiI double: si antepone lI long double: si antepone L
I Soppressione dell’input: mettendo “*” subito dopo “%”Non ci deve essere un argomento corrispondente allo specificatore diformato.
Esempio: Lettura di una data in formato gg/mm/aaaa oppuregg-mm-aaaa.int g, m, a;scanf("%d%*c%d%*c%d%*c", &g, &m, &a);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 157
La programmazione nel linguaggio C Espressioni booleane
Espressioni booleane
I Come gia sappiamo, il linguaggio deve consentire di descrivereespressioni booleane (guardie di condizionali e iterazione).
I In C non esiste un tipo Booleano =⇒ si usa il tipo int :
falso ⇐⇒ 0vero ⇐⇒ 1 (in realta qualsiasi valore diverso da 0)
Esempio: 2 > 3 ha valore 0 (ossia falso)5 > 3 ha valore 1 (ossia vero)
I Operatori relazionali del C
I <, >, <=, >= (minore, maggiore, minore o uguale, maggiore o uguale)— priorita alta
I ==, != (uguale, diverso) — priorita bassa
Esempio: temperatura <= 0 velocita > velocita max
voto == 30 anno != 2000
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 158
La programmazione nel linguaggio C Espressioni booleane
Operatori logici
I In ordine di priorita:I ! (negazione) — priorita altaI && (congiunzione)I || (disgiunzione) — priorita bassa
Semantica: a b !a a && b a || b0 0 1 0 00 1 1 0 11 0 0 0 11 1 0 1 1
0 . . . falso1 . . . vero (qualsiasi valore 6= 0)
Esempio:(a >= 10) && (a <= 20) vero (1) se 10 ≤ a ≤ 20(b <= -5) || (b >= 5) vero se |b| ≥ 5
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 159
La programmazione nel linguaggio C Espressioni booleane
I Le espressioni booleane vengono valutate da sinistra a destra:I con &&, appena uno degli operandi e falso, restituisce falso senza
valutare il secondo operandoI con ||, appena uno degli operandi e vero, restituisce vero senza
valutare il secondo operando
I Priorita tra operatori di diverso tipo:I not logico — priorita altaI aritmeticiI relazionaliI booleani (and e or logico) — priorita bassa
Esempio:a+2 == 3*b || !trovato && c < a/3
e equivalente a((a+2) == (3*b)) || ((!trovato) && (c < (a/3)))
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 160
La programmazione nel linguaggio C Istruzioni condizionali
Istruzione if-else
Sintassi:
if (espressione)istruzione1
else istruzione2
I espressione e un’espressione booleanaI istruzione1 rappresenta il ramo then (deve essere un’unica
istruzione)I istruzione2 rappresenta il ramo else (deve essere un’unica istruzione)
Semantica:1. viene prima valutata espressione2. se espressione e vera viene eseguita istruzione1
altrimenti (ovvero se espressione e falsa) viene eseguitaistruzione2
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 161
La programmazione nel linguaggio C Istruzioni condizionali
int temperatura;
printf("Quanti gradi ci sono? "); scanf("%d", &temperatura);if (temperatura >= 25)
printf("Fa caldo\n");else
printf("Si sta bene\n");
printf("Arrivederci\n");
=> Quanti gradi ci sono? 30 ←↩Fa caldoArrivederci=>
=> Quanti gradi ci sono? 18 ←↩Si sta beneArrivederci=>
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 162
La programmazione nel linguaggio C Istruzioni condizionali
Istruzione ifI E un’istruzione if-else in cui manca la parte else.
Sintassi:if (espressione)
istruzione
Semantica:1. viene prima valutata espressione2. se espressione e vera viene eseguita istruzione altrimenti non si fa
alcunche
Esempio:int temperatura;
scanf("%d", &temperatura);
if (temperatura >= 25)
printf("Fa caldo\n");printf("Arrivederci\n");
=> 18 ←↩Arrivederci
=> 30 ←↩Fa caldoArrivederci
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 163
La programmazione nel linguaggio C Istruzioni condizionali
Blocco
I La sintassi di if-else consente di avere un’unica istruzione nel ramothen (o nel ramo else).
I Se in un ramo vogliamo eseguire piu istruzioni dobbiamo usare unblocco.
Sintassi:
{istruzione-1...istruzione-n
}I Come gia sappiamo e come rivedremo piu avanti, un blocco puo
contenere anche dichiarazioni.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 164
La programmazione nel linguaggio C Istruzioni condizionali
Esempio: Dati mese ed anno, calcolare mese ed anno del mesesuccessivo.
int mese, anno, mesesucc, annosucc;
if (mese == 12){
mesesucc = 1;annosucc = anno + 1;
}else{
mesesucc = mese + 1;annosucc = anno;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 165
La programmazione nel linguaggio C Istruzioni condizionali
If annidati (in cascata)I Si hanno quando l’istruzione del ramo then o else e un’istruzione if o if-else.
Esempio: Data una temperatura, stampare un messaggio secondo laseguente tabella:
temperatura t messaggio30 < t Molto caldo20 < t ≤ 30 Caldo10 < t ≤ 20 Gradevole0 < t ≤ 10 Freddot ≤ 0 Molto freddo
if (temperatura > 30)printf("Molto caldo\n");
else if (temperatura > 20)printf("Caldo\n");
else if (temperatura > 10)printf("Gradevole\n");
else if (temperatura > 0)printf("Freddo\n");
elseprintf("Molto freddo\n");
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 166
La programmazione nel linguaggio C Istruzioni condizionali
Osservazioni:
I si tratta di un’unica istruzione if-elseif (temperatura > 30)printf("Molto caldo\n");
else ...
I non serve che la seconda condizione sia compostaif (temperatura > 30) printf("Molto caldo\n");else /* il valore di temperatura e’ <= 30 */
if (temperatura > 20)
Non c’e bisogno di una congiunzione del tipo(t <= 30) && (t > 20)(analogamente per gli altri casi).
I Attenzione: il seguente codiceif (temperatura > 30) printf("Molto caldo\n");if (temperatura > 20) printf("Caldo\n");ha ben altro significato (quale?)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 167
La programmazione nel linguaggio C Istruzioni condizionali
Ambiguita dell’elseif (a >= 0) if (b >= 0) printf("b positivo");else printf("???");
I printf("???") puo essere la parte elseI del primo if =⇒ printf("a negativo");I del secondo if =⇒ printf("b negativo");
I L’ambiguita sintattica si risolve considerando che un else fa sempreriferimento all’if piu vicino, dunqueif (a > 0)
if (b > 0)
printf("b positivo");
else
printf("b negativo");
I Perche un else si riferisca ad un if precedente, bisogna inserirequest’ultimo in un bloccoif (a > 0)
{ if (b > 0) printf("b positivo"); }else
printf("a negativo");
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 168
La programmazione nel linguaggio C Istruzioni condizionali
EsercizioLeggere un reale e stampare un messaggio secondo la seguente tabella:
gradi alcolici g messaggio
40 < g superalcolico20 < g ≤ 40 alcolico15 < g ≤ 20 vino liquoroso12 < g ≤ 15 vino forte10.5 < g ≤ 12 vino normaleg ≤ 10.5 vino leggero
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 169
La programmazione nel linguaggio C Istruzioni condizionali
Esempio: Dati tre valori che rappresentano le lunghezze dei lati diun triangolo, stabilire se si tratti di un triangolo equilatero, isoscele oscaleno.
Algoritmo: determina tipo di triangololeggi i tre laticonfronta i lati a coppie, fin quando non
hai raccolto una quantita di informazionisufficiente a prendere la decisione
stampa il risultato
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 170
La programmazione nel linguaggio C Istruzioni condizionali
main() {float primo, secondo, terzo;
printf("Lunghezze lati triangolo ? ");scanf("%f%f%f", &primo, &secondo, &terzo);
if (primo == secondo) {if (secondo == terzo)printf("Equilatero\n");
elseprintf("Isoscele\n");
}else {
if (secondo == terzo)printf("Isoscele\n");
else if (primo == terzo)printf("Isoscele\n");
elseprintf("Scaleno\n");
} }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 171
La programmazione nel linguaggio C Istruzioni condizionali
EsercizioRisolvere il problema del triangolo utilizzando il seguente algoritmo:
Algoritmo: determina tipo di triangolo con conteggioleggi i tre laticonfronta i lati a coppie contandoquante coppie sono uguali
if le coppie uguali sono 0e scalenoelse if le coppie uguali sono 1
e isosceleelse e equilatero
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 172
La programmazione nel linguaggio C Istruzioni condizionali
Istruzione switch
I Puo essere usata per realizzare una selezione a piu vie.
Sintassi:switch (espressione) {
case valore-1: istruzioni-1break;
...case valore-n: istruzioni-n
break;default : istruzioni-default
}Semantica:
1. viene valutata espressione2. viene cercato il primo i per cui il valore di espressione e uguale a
valore-i3. se si trova tale i, allora vengono eseguite istruzioni-i
altrimenti vengono eseguite istruzioni-default
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 173
La programmazione nel linguaggio C Istruzioni condizionali
Esempio:int giorno;...switch (giorno) {
case 1: printf("Lunedi’\n");break;
case 2: printf("Martedi’\n");break;
case 3: printf("Mercoledi’\n");break;
case 4: printf("Giovedi’\n");break;
case 5: printf("Venerdi’\n");break;
default : printf("Week end\n");}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 174
La programmazione nel linguaggio C Istruzioni condizionali
I Se abbiamo piu valori a cui corrispondono le stesse istruzioni,possiamo raggrupparli come segue:
case valore-1: case valore-2:istruzioni
break;
Esempio:int giorno;...switch (giorno) {
case 1:case 2:case 3:case 4:case 5: printf("Giorno lavorativo\n");
break;case 6:case 7: printf("Week end\n");default : printf("Giorno non valido\n");
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 175
La programmazione nel linguaggio C Istruzioni condizionali
Osservazioni sull’istruzione switch
I L’espressione usata per la selezione puo essere una qualsiasiespressione C che restituisce un valore intero.
I I valori specificati nei vari case devono invece essere costanti (omeglio valori noti a tempo di compilazione). In particolare, nonpossono essere espressioni in cui compaiono variabili.
Esempio: Il seguente frammento di codice e sbagliato:int a;
switch (a) {case a<0: printf("negativo\n");
/* ERRORE: a<0 non e’ una costante*/case 0: printf("nullo\n");case a>0: printf("positivo\n");
/* ERRORE: a>0 non e’ una costante*/
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 176
La programmazione nel linguaggio C Istruzioni condizionali
I In realta il C non richiede che nei case di un’istruzione switchl’ultima istruzione sia break.
Quindi, in generale la sintassi di un’istruzione switch e:
switch (espressione) {case valore-1: istruzioni-1...case valore-n: istruzioni-ndefault : istruzioni-default
}Semantica:
1. viene prima valutata espressione2. viene cercato il primo i per cui il valore di espressione e pari a
valore-i3. se si trova tale i, allora si eseguono in sequenza istruzioni-i,
istruzioni-(i+1), . . . , fino a quando non si incontra break o eterminata l’istruzione switch,altrimenti vengono eseguite istruzioni-default
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 177
La programmazione nel linguaggio C Istruzioni condizionali
Esempio: piu case di uno switch eseguiti in sequenza (corretto)int lati;
printf("Immetti il massimo numero di lati del poligono (al piu‘ 6): ");
scanf("%d", &lati);
printf("Poligoni con al piu‘ %d lati: ", lati);
switch (lati) {case 6: printf("esagono, ");
case 5: printf("pentagono, ");
case 4: printf("rettangolo, ");
case 3: printf("triangolo\n");break;
case 2: case 1: printf("nessuno\n");break;
default : printf("\nErrore: valore immesso > 6.\n");}
I N.B. Quando si omettono i break, diventa rilevante l’ordine in cuivengono scritti i vari case . Questo puo essere facile causa di errori.
E buona norma mettere break come ultima istruzione di ogni case
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 178
La programmazione nel linguaggio C Istruzioni condizionali
Esempio: piu case di uno switch eseguiti in sequenza (scorretto)int b;
printf("Immetti un numero tra 1 e 6: ");
scanf("%"., &b);
switch (b) {case 1: case 2: case 3: case 5: printf("Numero primo\n");case 4: case 6: printf("Numero non primo\n");default : printf("Valore non valido!\n");
}
=> 3←↩Numero primoNumero non primoValore non valido!=>
=> 4 ←↩Numero non primoValore non valido!=>
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 179
La programmazione nel linguaggio C Istruzioni iterative
Istruzioni iterativeEsempio: Leggere 5 interi, calcolarne la somma e stamparli.
I Variante non accettabile: 5 variabili, 5 istruzioni di lettura, 5 . . .int i1, i2, i3, i4, i5;scanf("%d", &i1):...scanf("%d", &i5);
printf("%d", i1 + i2 + i3 + i4 + i5);
I Variante migliore che utilizza solo 2 variabili:int somma, i;somma = 0;scanf("%d", &i);somma = somma + i;... /* per 5 volte */scanf("%d", &i);somma = somma + i;
printf("%d", somma);
=⇒ conviene pero usare un’istruzione iterativa
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 180
La programmazione nel linguaggio C Istruzioni iterative
Iterazione determinata e indeterminata
I Le istruzioni iterative permettono di ripetere determinate azioni piuvolte:
I un numero di volte fissato =⇒ iterazione determinataEsempio:fai un giro del parco di corsa per 10 volte
I finche una condizione rimane vera =⇒ iterazione indeterminataEsempio:finche’ non sei sazioprendi una ciliegia dal piatto e mangiala
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 181
La programmazione nel linguaggio C Istruzioni iterative
Istruzione while
Permette di realizzare l’iterazione in C.
Sintassi:
while (espressione)istruzione
I espressione e la guardia del ciclo
I istruzione e il corpo del ciclo (puo essere un blocco)
Semantica:1. viene valutata l’espressione2. se e vera si esegue istruzione e si torna ad eseguire l’intero while3. se e falsa si termina l’esecuzione del while
I Nota: se espressione e falsa all’inizio, il ciclo non fa nulla.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 182
La programmazione nel linguaggio C Istruzioni iterative
Iterazione determinata
Esempio: Stampa 100 asterischi.
I Si utilizza un contatore per contare il numero di asterischi stampati.Algoritmo: stampa di 100 asterischiinizializza il contatore a 0while il contatore e minore di 100{ stampa un ‘‘*’’
incrementa il contatore di 1 }I Implementazione:
int i;i = 0;while (i < 100) {putchar(’*’);i = i + 1;
}I come gia sappiamo, la variabile i viene detta variabile di controllo del
ciclo.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 183
La programmazione nel linguaggio C Istruzioni iterative
Iterazione determinata
Esempio: Leggere 10 interi, calcolarne la somma e stamparla.
I Si utilizza un contatore per contare il numero di interi letti.int conta, dato, somma;
printf("Immetti 10 interi: ");somma = 0;conta = 0;while (conta < 10) {scanf("%d", &dato);somma = somma + dato;conta = conta + 1;
}printf("La somma e’ %d\n", somma);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 184
La programmazione nel linguaggio C Istruzioni iterative
Esempio: Leggere un intero N seguito da N interi e calcolare lasomma di questi ultimi.
I Simile al precedente: il numero di ripetizioni necessarie non e noto almomento della scrittura del programma ma lo e al momentodell’esecuzione del ciclo.
int lung, conta, dato, somma;
printf("Immetti la lunghezza della sequenza ");printf("seguita dagli elementi della stessa: ");scanf("%d", &lung);somma = 0;conta = 0;while (conta < lung) {scanf("%d", &dato);somma = somma + dato;conta = conta + 1;
}printf("La somma e’ %d\n", somma);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 185
La programmazione nel linguaggio C Istruzioni iterative
Esempio: Leggere 10 interi positivi e stamparne il massimo.
I Si utilizza un massimo corrente con il quale si confronta ciascunnumero letto.
int conta, dato, massimo;printf("Immetti 10 interi: ");massimo = 0;conta = 0;while (conta < 10) {scanf("%d", &dato);if (dato > massimo)
massimo = dato;conta = conta + 1;
}printf("Il massimo e’ %d\n", massimo);
EsercizioLeggere 10 interi arbitrari e stamparne il massimo.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 186
La programmazione nel linguaggio C Istruzioni iterative
Istruzione forI I cicli visti fino ad ora hanno queste caratteristiche comuni:
I utilizzano una variabile di controlloI la guardia verifica se la variabile di controllo ha raggiunto un limite
prefissatoI ad ogni iterazione si esegue un’azioneI al termine di ogni iterazione viene incrementato (decrementato) il
valore della variabile di controllo
Esempio: Stampare i numeri pari da 0 a N.i = 0; /* Inizializzazione della var. di controllo */while (i <= N) { /* guardia */printf("%d ", i); /* Azione da ripetere */i=i+2; /* Incremento var. di controllo */
}I L’istruzione for permette di gestire direttamente questi aspetti:
for (i = 0; i <= N; i=i+2)printf("%d", i);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 187
La programmazione nel linguaggio C Istruzioni iterative
Sintassi:
for (istr-1; espr-2; istr-3)istruzione
I istr-1 serve a inizializzare la variabile di controllo
I espr-2 e la verifica di fine ciclo
I istr-3 serve a incrementare la variabile di controllo alla fine delcorpo del ciclo
I istruzione e il corpo del ciclo
Semantica: l’istruzione for precedente e equivalente aistr-1;while (espr-2) {
istruzioneistr-3
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 188
La programmazione nel linguaggio C Istruzioni iterative
Esempio:for (i = 1; i <= 10; i=i+1) =⇒ i: 1, 2, 3, . . . , 10for (i = 10; i >= 1; i=i-1) =⇒ i: 10, 9, 8, . . . , 2, 1for (i = -4; i <= 4; i = i+2) =⇒ i: -4, -2, 0, 2, 4for (i = 0; i >= -10; i = i-3) =⇒ i: 0, -3, -6, -9
I In realta, la sintassi del for efor (espr-1; espr-2; espr-3)istruzione
dove espr-1, espr-2 e espr-3 sono delle espressioni qualsiasi (in Canche l’assegnamento e un’espressione . . . ).
I E buona prassi:I usare ciascuna espr-i in base al significato descritto primaI non modificare la variabile di controllo nel corpo del ciclo
I Ciascuna delle tre espr-i puo anche mancare:I i “;” vanno messi lo stessoI se manca espr-2 viene assunto il valore vero
I Se manca una delle tre espr-i e meglio usare un’istruzione while
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 189
La programmazione nel linguaggio C Istruzioni iterative
Esempio: Leggere 10 interi positivi e stamparne il massimo.
int conta, dato, massimo;printf("Immetti 10 interi: ");massimo = 0;for (conta=0; conta<10; conta=conta+1){
scanf("%d", &dato);if (dato > massimo)massimo = dato;
}
printf("Il massimo e‘ %d\n", massimo);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 190
La programmazione nel linguaggio C Istruzioni iterative
Iterazione indefinita
I In alcuni casi il numero di iterazioni da effettuare non e noto prima diiniziare il ciclo, perche dipende dal verificarsi di una condizione.
Esempio: Leggere una sequenza di interi che termina con 0 ecalcolarne la somma.
Input: n1, . . . , nk, 0 (con ni 6= 0)
Output:k∑
i=1ni
int dato, somma = 0;
scanf("%d", &dato);while (dato != 0) {somma = somma + dato;scanf("%d", &dato);
}printf("%d", somma);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 191
La programmazione nel linguaggio C Istruzioni iterative
Istruzione do-while
I Nell’istruzione while la condizione di fine ciclo viene controllataall’inizio di ogni iterazione.
I L’istruzione do-while e simile all’istruzione while, ma la condizioneviene controllata alla fine di ogni iterazione
Sintassi:
doistruzione
while (espressione);
Semantica: e equivalente aistruzionewhile (espressione)istruzione
=⇒ una iterazione viene eseguita comunque.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 192
La programmazione nel linguaggio C Istruzioni iterative
Esempio: Lunghezza di una sequenza di interi terminata da 0,usando do-while.
main() {int lunghezza = 0; /* lunghezza della sequenza */int dato; /* dato letto di volta in volta */
printf("Inserisci una sequenza di interi (0 fine seq.)\n");
do {scanf("%d", &dato);lunghezza=lunghezza+1;
} while (dato != 0);
printf("La sequenza e’ lunga %d\n", lunghezza - 1);
}
I Nota: lo 0 finale non e conteggiato (non fa parte della sequenza, fada terminatore)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 193
La programmazione nel linguaggio C Istruzioni iterative
Esempio: Leggere due interi positivi e calcolarne il massimo comundivisore.MCD(12, 8) = 4MCD(12, 6) = 6MCD(12, 7) = 1
I Sfruttando direttamente la definizione di MCD
I osservazione: 1≤ MCD(m,n)≤ min(m,n)=⇒ si provano i numeri compresi tra 1 e min(m,n)
I conviene iniziare da min(m,n) e scendere verso 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 194
La programmazione nel linguaggio C Istruzioni iterative
Algoritmo: stampa MCD di due interi positivi letti da tastiera
leggi m ed ninizializza mcd al minimo tra m ed nwhile mcd > 1 e non si e’ trovato un divisore comune{
if mcd divide sia m che nsi e’ trovato un divisore comune
else decrementa mcd di 1}stampa mcd
OsservazioniI il ciclo termina sempre perche ad ogni iterazione
I o si e trovato un divisoreI o si decrementa mcd di 1 (al piu si arriva a 1)
I per verificare se si e trovato il MCD si utilizza una variabile booleana(nella guardia del ciclo)
I Implementazione in C . . .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 195
La programmazione nel linguaggio C Istruzioni iterative
int m, n; /* i due numeri letti */
int mcd; /* il massimo comun divisore */
int trovato = 0; /* var. booleana: inizialmente false */
if (m <= n) /*inizializza mcd al minimo tra m e n*/
mcd = m;else
mcd = n;while (mcd > 1 && !trovato)
if ((m % mcd == 0) && (n % mcd == 0))/* mcd divide entrambi */
trovato = 1;else
mcd = mcd -1;printf("MCD di %d e %d: %d", m, n, mcd);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 196
La programmazione nel linguaggio C Istruzioni iterative
Quante volte viene eseguito il ciclo?
I caso migliore: 1 volta (quando m divide n o viceversa)es. MCD(500, 1000)
I caso peggiore: min(m,n) volte (quando MCD(m,n)=1)es. MCD(500, 1001)
I l’algoritmo si comporta male se m e n sono grandi e MCD(m,n) epiccolo
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 197
La programmazione nel linguaggio C Istruzioni iterative
Metodo di Euclide per il calcolo del MCDI Gia visto nell’introduzione (pseudo-linguaggio). Permette di ridursi
piu velocemente a numeri piu piccoli, sfruttando le seguenti proprieta:MCD(x, x) = xMCD(x, y) = MCD(x-y, y) se x>yMCD(x, y) = MCD(x, y-x) se y>x
I I divisori comuni di m ed n, con m>n, sono anche divisori di m-n.Es.: MCD(12, 8) = MCD(12-8, 8) = MCD(4, 8-4) = 4
I Come si ottiene un algoritmo?Si applica ripetutamente il procedimento fino a che non si ottiene chem=n.
Esempio:
m n maggiore - minore210 63 147147 63 8484 63 2121 63 4221 42 2121 21
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 198
La programmazione nel linguaggio C Istruzioni iterative
Algoritmo: di Euclide per il calcolo del MCD
int m,n;scanf("%d%d", &m, &n);while (m != n)
if (m > n)m = m - n;
elsen = n - m;
printf("MCD: %d\n", m);
I Cosa succede se m=n=0?
=⇒ il risultato e 0
I E se m=0 e n6= 0 (o viceversa)?
=⇒ si entra in un ciclo infinito
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 199
La programmazione nel linguaggio C Istruzioni iterative
I Per assicurarci che l’algoritmo venga eseguito su valori corretti,possiamo inserire una verifica sui dati in ingresso, attraverso un ciclodi lettura
Proposte?
do {printf("Immettere due interi positivi: ");scanf("%d%d", &m, &n);if (m <= 0 || n <= 0)
printf("Errore: i numeri devono essere > 0!\n");} while (m <= 0 || n<= 0);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 200
La programmazione nel linguaggio C Istruzioni iterative
Metodo di Euclide con i resti per il calcolo del MCD
I Cosa succede se m � n?
Esempio:
MCD(1000, 2) MCD(1001, 500)1000 2 1001 500998 2 501 500996 2 1 500
. . . . . .2 2 1 1
I Come possiamo comprimere questa lunga sequenza di sottrazioni?
I Metodo di Euclide: sia
m = n·k + r (con 0≤ r< m)
MCD(m, n) = n se r=0MCD(m, n) = MCD(r, n) se r6=0
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 201
La programmazione nel linguaggio C Istruzioni iterative
Algoritmo di Euclide con i resti per il calcolo del MCD
leggi m ed nwhile m ed n sono entrambi 6= 0{ sostituisci il maggiore tra m ed n con
il resto della divisione del maggiore per il minore}stampa il numero tra i due che e’ diverso da 0
EsercizioTradurre l’algoritmo in C
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 202
La programmazione nel linguaggio C Istruzioni iterative
Cicli annidati
I Il corpo di un ciclo puo contenere a sua volta un ciclo.
Esempio: Stampa della tavola pitagorica.Algoritmo
for ogni riga tra 1 e 10{ for ogni colonna tra 1 e 10stampa riga * colonna
stampa un a capo }I Traduzione in C
int riga, colonna;const int Nmax = 10; /* indica il numero di righe e dicolonne */for (riga = 1; riga <= Nmax; riga=riga+1) {
for (colonna = 1; colonna <= Nmax; colonna=colonna+1)printf("%d ", riga * colonna);
putchar(’\n’); }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 203
La programmazione nel linguaggio C Operatori di assegnamento
Assegnamento e altri operatori
I In C, l’operazione di assegnamento x = exp e un’espressioneI il valore dell’espressione e il valore di exp (che e a sua volta
un’espressione)I la valutazione dell’espressione x = exp ha un side-effect: quello di
assegnare alla variabile x il valore di exp
I Dunque in realta, “=” e un operatore (associativo a destra).Esempio: Qual’e l’effetto di x = y = 4 ?
I E equivalente a: x = (y = 4)I y = 4 . . . espressione di valore 4 con modifica (side-effect) di yI x = (y = 4) . . . espressione di valore 4 con ulteriore modifica su x
I L’eccessivo uso di assegnamenti come espressioni rende il codicedifficile da comprendere e quindi correggere/modificare.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 205
La programmazione nel linguaggio C Operatori di assegnamento
Operatori di incremento e decremento
I Assegnamenti del tipo:i = i + 1i = i - 1
sono molto comuni.
I operatore di incremento: ++I operatore di decremento: --
I In realta ++ corrisponde a due operatori:I postincremento: i++
I il valore dell’espressione e il valore di iI side-effect: incrementa i di 1
I L’effetto di
int i,j;i=6;j=i++;
e j=6, i=7.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 206
La programmazione nel linguaggio C Operatori di assegnamento
I preincremento: ++iI il valore dell’espressione e il valore di i+1I side-effect: incrementa i di 1
I L’effetto di
int i,j;i=6;j=++i;
e j=7, i=7.
(analogamente per i-- e --i)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 207
La programmazione nel linguaggio C Operatori di assegnamento
I Nota sull’uso degli operatori di incremento e decrementoEsempio: Istruzione x y z
1 int x, y, z; ? ? ?2 x = 4; 4 ? ?3 y = 2; 4 2 ?
4a z = (x + 1) + y; 4 2 7
4b z = (x++) + y; 5 2 6
4c z = (++x) + y; 5 2 7
I N.B.: Non usare mai in questo modo!In un’istruzione di assegnamento non ci devono essere altri side-effect(oltre a quello dell’operatore di assegnamento) !!!
I Riscrivere, ad esempio, come segue:4b: z = (x++) + y; =⇒ z = x + y;
x++;
4c: z = (++x) + y; =⇒ x++;z = x + y;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 208
La programmazione nel linguaggio C Operatori di assegnamento
Ordine di valutazione degli operandiI In generale il C non stabilisce quale e l’ordine di valutazione degli
operandi nelle espressioni.Esempio: int x, y, z;x = 2;y = 4;z = x++ + (x * y);
I Quale e il valore di z?
I se viene valutato prima x++: 2 + (3 * 4) = 14I se viene valutato prima x*y: (2 * 4) + 2 = 10
Forme abbreviate dell’assegnamento
a = a + b; =⇒ a += b;a = a - b; =⇒ a -= b;a = a * b; =⇒ a *= b;a = a / b; =⇒ a /= b;a = a % b; =⇒ a %= b;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 209
La programmazione nel linguaggio C Array
Tipi di dato strutturati: Array
I I tipi di dato visti finora sono tutti semplici: int, char, float, . . .
I ma i dati manipolati nelle applicazioni reali sono spesso complessi (ostrutturati)
I Gli array sono uno dei tipi di dato strutturatiI sono composti da elementi omogenei (tutti dello stesso tipo)I ogni elemento e identificato all’interno dell’array da un numero
d’ordine detto indice dell’elementoI il numero di elementi dell’array e detto lunghezza (o dimensione)
dell’array
I Consentono di rappresentare tabelle, matrici, matrici n-dimensionali,. . .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 210
La programmazione nel linguaggio C Array
Array monodimensionali (o vettori)
I Supponiamo di dover rappresentare e manipolare la classifica di uncampionato cui partecipano 16 squadre.
I E del tutto naturale pensare ad una tabella
Classifica
Squadra A Squadra B . . . Squadra C
1o posto 2o posto 16o posto
che evolve con il procedere del campionato
Classifica
Squadra B Squadra A . . . Squadra C
1o posto 2o posto 16o posto
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 211
La programmazione nel linguaggio C Array
Sintassi: dichiarazione di variabile di tipo vettoretipo-elementi nome-array [lunghezza];
Esempio: int vet[6];dichiara un vettore di 6 elementi, ciascuno di tipo intero.
I All’atto di questa dichiarazione vengono riservate (allocate) 6locazioni di memoria consecutive, ciascuna contenente un intero. 6 ela lunghezza del vettore.
I La lunghezza di un vettore deve essere costante (nota a tempo dicompilazione).
I Ogni elemento del vettore e una variabile identificata dal nome delvettore e da un indice
Sintassi: elemento di array nome-array[espressione];
Attenzione: espressione deve essere di tipo intero ed il suo valoredeve essere compreso tra 0 a lunghezza-1.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 212
La programmazione nel linguaggio C Array
I Esempio:indice elemento variabile
0 ? vet[0]
1 ? vet[1]
2 ? vet[2]
3 ? vet[3]
4 ? vet[4]
5 ? vet[5]
I vet[i] e l’elemento del vettore vet di indice i.Ogni elemento del vettore e una variabile.
int vet[6], a;
vet[0] = 15;
a = vet[0];
vet[1] = vet[0] + a;
printf("%d", vet[0] + vet[1]);
I vet[0], vet[1], ecc. sono variabili intere come tutte le altre e dunquepossono stare a sinistra dell’assegnamento (es. vet[0] = 15), cosi’ comeall’interno di espressioni (es. vet[0] + a).
I Come detto, l’indice del vettore e un’espressione.index = 2;
vet[index+1] = 23;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 213
La programmazione nel linguaggio C Array
Manipolazione di vettoriI avviene solitamente attraverso cicli forI l’indice del ciclo varia in genere da 0 a lunghezza-1I spesso conviene definire la lunghezza come una costante attraverso la
direttiva #define
Esempio: Lettura e stampa di un vettore.#include <stdio.h>
#define LUNG 5
main ()
{int v[LUNG]; /* vettore di LUNG elementi, indicizzati da 0 a LUNG-1 */
int i;
for (i = 0; i < LUNG; i++) {printf("Inserisci l’elemento di indice %d: ", i);
scanf("%d", &v[i]);
}printf("Indice Elemento\n");for (i = 0; i < LUNG; i++) {
printf("%6d %8d\n", i, v[i]); }}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 214
La programmazione nel linguaggio C Array
Inizializzazione di vettoriI Gli elementi del vettore possono essere inizializzati con valori costanti
(valutabili a tempo di compilazione) contestualmente alla dichiarazione delvettore .
Esempio: int n[4] = {11, 22, 33, 44};
I l’inizializzazione deve essere contestuale alla dichiarazione
Esempio:int n[4];
n = {11, 22, 33, 44}; =⇒ errore!
I se i valori iniziali sono meno degli elementi, i rimanenti vengono posti a 0int n[10] = {3}; azzera i rimanenti 9 elementi del vettorefloat af[5] = {0.0}; pone a 0.0 i 5 elementiint x[5] = {}; errore!
I se ci sono piu inizializzatori di elementi, si ha un errore a tempo dicompilazioneEsempio: int v[2] = {1, 2, 3}; errore!
I se si mette una sequenza di valori iniziali, si puo omettere la lunghezza(viene presa la lunghezza della sequenza)Esempio: int n[] = {1, 2, 3}; equivale a
int n[3] = {1, 2, 3};
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 215
La programmazione nel linguaggio C Array
I In C l’unica operazione possibile sugli array e l’accesso ai singolielementi.
I Ad esempio, non si possono effettuare direttamente delle assegnazionitra vettori.
Esempio:int a[3] = {11, 22, 33};int b[3];b = a; errore!
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 216
La programmazione nel linguaggio C Array
Esempi
I Calcolo della somma degli elementi di un vettore.
int a[10], i, somma = 0;...for (i = 0; i < 10; i++)
somma += a[i];printf("%d", somma);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 217
La programmazione nel linguaggio C Array
I Leggere N interi e stampare i valori maggiori di un valore intero yletto in input.#include <stdio.h>#define N 4main() {int ris[N];int y, i;printf("Inserire i %d valori:\n", N);for (i = 0; i < N; i++) {printf("Inserire valore n. %d: ", i+1);scanf("%d", &ris[i]); }
printf("Inserire il valore y:\n");scanf("%d", &y);
printf("Stampa i valori maggiori di %d:\n", y);for (i = 0; i < N; i++)
if (ris[i] > y)printf("L’elemento %d: %d e’ maggiore di %d\n",
i+1, ris[i],y);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 218
La programmazione nel linguaggio C Array
I Leggere una sequenza di caratteri terminata dal carattere \n di finelinea e stampare le frequenze delle cifre da ’0’ a ’9’.
I utilizziamo un vettore freq di 10 elementi nel quale memorizziamo lefrequenze dei caratteri da ’0’ a ’9’
0 1 2 3 4 5 6 7 8 9. . . . . .
freq
freq[0] conta il numero di occorrenze di ’0’
. . .
freq[9] conta il numero di occorrenze di ’9’
I utilizziamo un ciclo per l’acquisizione dei caratteri in cui aggiorniamouna delle posizioni dell’array tutte le volte che il carattere letto e unacifra
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 219
La programmazione nel linguaggio C Array
int i; char ch;
int freq[10] = {0};do {
ch = getchar();
switch (ch) {case ’0’: freq[0]++; break;case ’1’: freq[1]++; break;case ’2’: freq[2]++; break;case ’3’: freq[3]++; break;case ’4’: freq[4]++; break;case ’5’: freq[5]++; break;case ’6’: freq[6]++; break;case ’7’: freq[7]++; break;case ’8’: freq[8]++; break;case ’9’: freq[9]++; break;}
} while (ch != ’\n’);printf("Le frequenze sono:\n");for (i = 0; i < 10; i++)
printf("Freq. di %d: %d\n", i, freq[i]);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 220
La programmazione nel linguaggio C Array
I Nel ciclo do-while, il comando switch puo essere rimpiazzato da unif come segue
if (ch >= ’0’ && ch <= ’9’)freq[ch - ’0’]++;
Infatti:
I i codici dei caratteri da ’0’ a ’9’ sono consecutiviI dato un carattere ch, l’espressione intera ch - ’0’ e la distanza del
codice di ch dal codice del carattere ’0’. In particolare:I ’0’ - ’0’ = 0I ’1’ - ’0’ = 1I . . .I ’9’ - ’0’ = 9
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 221
La programmazione nel linguaggio C Array
I Leggere da tastiera i risultati (double) di 20 esperimenti. Stampare ilnumero d’ordine ed il valore degli esperimenti per i quali il risultato e‘minore del 50% della media.#include <stdio.h>
#define DIM 20
main() {double ris[DIM], media;
int i;
/* inserimento dei valori */
printf("Inserire i %d risultati dell’esperimento:\n", DIM);
for (i = 0; i < DIM; i++) {printf("Inserire risultato n. %d: ", i);
scanf("%g", &ris[i]); }/* calcolo della media */
media = 0.0;
for (i = 0; i < DIM; i++)
media = media + ris[i];
media = media/DIM;
printf("Valore medio: %g\n", media);
/* stampa dei valori minori di media*0.5 */
printf("Stampa dei valori minori di media*0.5:\n");for (i = 0; i < DIM; i++)
if (ris[i] < media * 0.5)
printf("Risultato n. %d: %g\n", i, ris[i]); }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 222
La programmazione nel linguaggio C Array
Array multidimensionali
Sintassi: dichiarazionetipo-elementi nome-array [lung1][lung2]· · · [lungn];
Esempio: int mat[3][4]; =⇒ matrice 3×4
I Per ogni dimensione i l’indice va da 0 a lungi -1.colonne
0 1 2 30 ? ? ? ?
righe 1 ? ? ? ?2 ? ? ? ?
Esempio: int marketing[10][5][12](indici potrebbero rappresentare: prodotti, venditori, mesi dell’anno)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 223
La programmazione nel linguaggio C Array
Accesso agli elementi di una matriceint i, mat[3][4];...i = mat[0][0]; elemento di riga 0 e colonna 0 (primo elemento)
mat[2][3] = 28; elemento di riga 2 e colonna 3 (ultimo elemento)
mat[2][1] = mat[0][0] * mat[1][3];
I Come per i vettori, l’unica operazione possibile sulle matrici el’accesso agli elementi tramite l’operatore [].
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 224
La programmazione nel linguaggio C Array
Esempio: Lettura e stampa di una matrice.#include <stdio.h>#define RIG 2#define COL 3main(){int mat[RIG][COL];int i, j;/* lettura matrice */printf("Lettura matrice %d x %d;\n", RIG, COL);for (i = 0; i < RIG; i++)
for (j = 0; j < COL; j++)scanf("%d", &mat[i][j]);
/* stampa matrice */printf("La matrice e’:\n");for (i = 0; i < RIG; i++) {
for (j = 0; j < COL; j++)printf("%6d ", mat[i][j]);
printf("\n"); } /* a capo dopo ogni riga */
}prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 225
La programmazione nel linguaggio C Array
Esempio: Programma che legge due matrici M×N (ad esempio4×3) e calcola la matrice somma.for (i = 0; i < M; i++)
for (j = 0; j < N; j++)c[i][j] = a[i][j] + b[i][j];
Inizializzazione di matrici
int mat[2][3] = {{1,2,3}, {4,5,6}};1 2 3
4 5 6int mat[2][3] = {1,2,3,4,5,6};
int mat[2][3] = {{1,2,3}};1 2 3
0 0 0int mat[2][3] = {1,2,3};
int mat[2][3] = {{1}, {2,3}};1 0 0
2 3 0
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 226
La programmazione nel linguaggio C Array
EsercizioProgramma che legge una matrice A (M×P) ed una matrice B(P×N) e calcola la matrice C prodotto di A e B
I La matrice C e di dimensione M×N.
I Il generico elemento Cij di C e dato da:
Cij =P−1∑k=0
Aik · Bkj
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 227
La programmazione nel linguaggio C Array
Soluzione#define M 3
#define P 4
#define N 2
int a[M][P], b[P][N], c[M][N];
...
/* calcolo prodotto */
for (i = 0; i < M; i++)
for (j = 0; j < N; j++) {c[i][j] = 0;
for (k = 0; k < P; k++)
c[i][j] = c[i][j] + a[i][k] * b[k][j];
}
I Tutti gli elementi di c possono essere inizializzati a 0 al momentodella dichiarazione:int a[M][P], b[P][N], c[M][N] = 0;
...
for (i = 0; i < M; i++)
for (j = 0; j < N; j++)
for (k = 0; k < P; k++)
c[i][j] += a[i][k] * b[k][j];
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 228
La programmazione nel linguaggio C Puntatori
PuntatoriEsempio: int a = 5;
I Proprieta della variabile a:
nome: atipo: intvalore: 5indirizzo: fissato una volta per tutte (es. A010 )
A00E · · ·A010 5A012 · · ·
I Finora abbiamo usato solo le prime tre proprieta. Come si usal’indirizzo?
I operatore indirizzo “&” - si applica ad una variabile=⇒ nell’esempio &a ha valore 0xA010 (indirizzo in esadecimale)
I Gli indirizzi si utilizzano nelle variabili di tipo puntatore, dettesemplicemente puntatori.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 229
La programmazione nel linguaggio C Puntatori
Puntatori
Esempio: int *pi;
I E una dichiarazione della varibile pi che ha tipo puntatore a intero
I E una variabile come tutte le altre, con le seguenti proprieta:
nome: pitipo: puntatore ad intero (ovvero, indirizzo di un intero)valore: inizialmente casualeindirizzo: fissato una volta per tutte
I Piu in generale:Sintassi tipo *variabile;
I Al solito, piu variabili dello stesso tipo possono essere dichiarate sullastessa linea
tipo *variabile-1, ..., *variabile-n;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 230
La programmazione nel linguaggio C Puntatori
Esempio:int *pi1, *pi2, i, *pi3, j;float *pf1, f, *pf2;
I Abbiamo dichiarato:pi1, pi2, pi3 di tipo puntatore ad inti, j di tipo intpf1, pf2 di tipo puntatore a floatf di tipo float
I Una variabile puntatore puo essere inizializzata usando l’operatore diindirizzo.Esempio: pi = &a;
I il valore di pi viene inizializzato all’indirizzo della variabile aI si dice che pi punta ad a ovvero che a e l’oggetto puntato da piI lo rappresenteremo spesso cosi’:
pi a
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 231
La programmazione nel linguaggio C Puntatori
Prima p=&a Dopo
A00E · · ·A010 5 aA012 · · ·
· · ·A200 ? piA202 · · ·
· · ·A200 A010 piA202 · · ·
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 232
La programmazione nel linguaggio C Puntatori
Operatore di dereferenziamento “*”
I Applicato ad una variabile puntatore fa riferimento all’oggettopuntato.Esempio:int *pi; /* dich. di puntatore ad intero */int a = 5, b; /* dich. variabili intere */
pi = &a; /* pi punta ad a ==> *pi sta per a */b = *pi; /* assegna a b il valore della variabile puntata
da pi, ovvero il valore di a, ovvero 5 */*pi = 9; /* assegna 9 alla variabile puntata da pi,
ovvero ad a */
I N.B. Se pi e di tipo int *, allora *pi e di tipo int.I Non confondere le due occorrenze di “*”:
I “*” in una dichiarazione serve per dichiarare una variabile di tipopuntatore, es. int *pi;
I “*” in un’espressione e l’operatore di dereferenziamento, es. b = *pi;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 233
La programmazione nel linguaggio C Puntatori
Operatori di dereferenziamento “*” e di indirizzo “&”
I hanno priorita piu elevata degli operatori binari
I “*” e associativo a destraEs.: **p e equivalente a *(*p)
I “&” puo essere applicato solo ad una variabile;&a non e una variabile =⇒ “&” non e associativo
I “*” e “&” sono uno l’inverso dell’altroI data la dichiarazione int a;
*&a e un modo alternativo per denotare a (sono entrambi variabili)I data la dichiarazione int *pi;
&*pi ha valore (un indirizzo) uguale al valore di pipero:• pi e una variabile• &*pi non lo e (ad esempio, non puo essere usato a sinistra di “=”)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 234
La programmazione nel linguaggio C Puntatori
Stampa di puntatori
I I puntatori si possono stampare con printf e specificatore di formato“%p” (stampa in formato esadecimale).Esempio: A00E · · ·
A010 5 aA012 A010 pi
· · ·int a = 5, *pi;pi = &a;printf("ind. di a = %p\n", &a); /* stampa 0xA010 */printf("val. di pi = %p\n", pi); /* stampa 0xA010 */printf("val. di &*pi = %p\n", &*pi); /* stampa 0xA010 */printf("val. di a = %d\n", a); /* stampa 5 */printf("val. di *pi = %d\n", *pi); /* stampa 5 */printf("val. di *&a = %d\n", *&a); /* stampa 5 */
I Si puo usare %p anche con scanf, ma ha poco senso leggere unindirizzo.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 235
La programmazione nel linguaggio C Puntatori
Esempio: Scambio del valore di due variabili.
int a = 10, b = 20, temp;temp = a;a = b;b = temp;
Tramite puntatori:int a = 10, b = 20, temp;int *pa, *pb;
pa = &a; /* *pa diventa un alias per a */pb = &b; /* *pb diventa un alias per b */
temp = *pa;*pa = *pb;*pb = temp;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 236
La programmazione nel linguaggio C Puntatori
Inizializzazione di variabili puntatoreI I puntatori (come tutte le altre variabili) devono essere inizializzati
prima di poter essere usati.
=⇒ E un errore dereferenziare una variabile puntatore noninizializzata.
Esempio: int a, *pi;A00E · · ·A010 ? aA012 F802 pi
· · ·F802 412F804 · · ·a = *pi; =⇒ ad a viene assegnato il valore 412*pi = 500; =⇒ scrive 500 nella cella di indirizzo F802
I Non sappiamo a cosa corrisponde questa cella di memoria!!!=⇒ la memoria puo venire corrotta
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 237
La programmazione nel linguaggio C Puntatori
Tipo di variabili puntatoreI Il tipo di una variabile puntatore e “puntatore a tipo”. Il suo valore e
un indirizzo.
I I tipi puntatore sono indirizzi e non interi.
int a, *pi;a = pi;
I Compilando si ottiene un warning:“assignment makes integer from pointer without a cast”
I Due variabili di tipo puntatore a tipi diversi sono incompatibili.
int x, *pi; float *pf;
x = pi; assegnazione int* a intwarning: “assignment makes integer from pointer . . . ”
pf = x; assegnazione int a float*warning: “assignment makes pointer from integer . . . ”
pi = pf; assegnazione float* a int*warning: “assignment from incompatible pointer type”
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 238
La programmazione nel linguaggio C Puntatori
I Perche il C distingue tra puntatori di tipo diverso?
I Se tutti i tipi puntatore fossero identici non sarebbe possibiledeterminare a tempo di compilazione il tipo di *p.
Esempio:puntatore p;int i; char c; float f;
I Potrei scrivere:p = &c;p = &i;p = &f;
I Il tipo di *p verrebbe a dipendere dall’ultima assegnazione che e statafatta (nota solo a tempo di esecuzione).
I Ad esempio, quale sarebbe il significato di / in i/*p: divisione interao reale?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 239
La programmazione nel linguaggio C Puntatori
Funzione sizeof con puntatoriI La funzione sizeof restituisce l’occupazione in memoria in byte di
una variabile o di un tipo.Puo essere applicata anche ad un tipo puntatore.
I Tutti i puntatori sono indirizzi =⇒ occupano lo spazio di memoria diun indirizzo.
I L’oggetto puntato ha invece la dimensione del tipo puntato.char *pc;int *pi;double *pd;printf("%d %d %d ", sizeof(pc), sizeof(pi), sizeof(pd));printf("%d %d %d\n", sizeof(char *), sizeof(int *),
sizeof(double *));printf("%d %d %d ", sizeof(*pc), sizeof(*pi), sizeof(*pd));printf("%d %d %d\n", sizeof(char), sizeof(int),
sizeof(double *));
4 4 4 4 4 41 2 8 1 2 8
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 240
La programmazione nel linguaggio C Puntatori
Operazioni con puntatoriSui puntatori si possono effettuare diverse operazioni:
I di dereferenziamentoEsempio:int *p, i;...
i = *p;
Il valore della variabile intera i e ora lo stesso del valore dell’interopuntato da p.
I di assegnamentoEsempio: int *p, *q;...
p = q;
I N.B. p e q devono essere dello stesso tipo (altrimenti bisogna usarel’operatore di cast).
Dopo l’assegnamento precedente, p punta allo stesso intero a cuipunta q.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 241
La programmazione nel linguaggio C Puntatori
I di confrontoEsempio:if (p == q) ...I due puntatori hanno lo stesso valore.
Esempio:if (p > q) ...
Ha senso? Con quello che abbiamo visto finora no. Vedremo che cisono situazioni in cui ha senso.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 242
La programmazione nel linguaggio C Puntatori
Aritmetica dei puntatori
Sui puntatori si possono anche effettuare operazioni aritmetiche, conopportune limitazioni
I somma o sottrazione di un intero
I sottrazione di un puntatore da un altro
Somma e sottrazione di un interoSe p e un puntatore a tipo e il suo valore e un certo indirizzo ind, ilsignificato di p+1 e il primo indirizzo utile dopo ind per l’accesso e lacorretta memorizzazione di una variabile di tipo tipo.Esempio:int *p, *q;....q = p+1;Se il valore di p e l’indirizzo 100, il valore di q dopo l’assegnamento e 104(assumendo che un intero occupi 4 byte).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 243
La programmazione nel linguaggio C Puntatori
I Quindi il valore calcolato in corrispondenza di un’operazione del tipop+i dipende dal tipo di p (analogamente per un’operazione del tipop-i).
Esempio:int *pi;*pi = 15;pi=pi+1; =⇒ pi punta al prossimo int (4 byte dopo)
Esempio:double *pd;*pd = 12.2;pd = pd+3; =⇒ pd punta a 3 double dopo (24 byte dopo)
Esempio:char *pc;*pc = ’A’;pc = pc - 5; =⇒ pc punta a 5 char prima (5 byte prima)
I Possiamo anche scrivere: pi++; pd+=3; pc-=5;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 244
La programmazione nel linguaggio C Puntatori
Puntatore a puntatore
I Le variabili di tipo puntatore sono variabili come tutte le altre: inparticolare hanno un indirizzo che puo costituire il valore di un’altravariabile di tipo puntatore a puntatore.
Esempio:int *pi, **ppi, x=10;pi = &x;ppi = πprintf("pi = %p ppi = %p *ppi = %p\n", pi, ppi, *ppi);printf("*pi = %d **ppi = %d x = %d\n", *pi, **ppi, x);
pi = 0x22ef34 ppi = 0x22ef3c *ppi = 0x22ef34*pi = 10 **ppi = 10 x = 10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 245
La programmazione nel linguaggio C Puntatori
Esempi
int a, b, *p, *q;a=10;b=20;p = &a;q = &b;*q = a + b;a = a + *q;q = p;*q = a + b;printf("a=%d b=%d *p=%d *q=%d, a,b,*p,*q);
Quali sono i valori stampati dal programma?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 246
La programmazione nel linguaggio C Puntatori
Esempi (contd.)
int *p, **q;int a=10, b=20;q = &p;p = &a;*p = 50;**q = 100;*q = &b;*p = 50;a = a+b;printf("a=%d b=%d *p=%d **q=%d\n", a, b, *p, **q);
Quali sono i valori stampati dal programma?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 247
La programmazione nel linguaggio C Puntatori
Relazione tra vettori e puntatori
I In generale non sappiamo cosa contengono le celle di memoriaadiacenti ad una data cella.
I L’unico caso in cui sappiamo quali sono le locazioni di memoriasuccessive e cosa contengono e quando utilizziamo dei vettori.
I In C il nome di un vettore e in realta un puntatore, inizializzatoall’inidirizzo dell’elemento di indice 0.
int vet[10]; =⇒ vet e &vet[0] hanno lo stesso valore (un indirizzo)
=⇒ printf("%p %p", vet, &vet[0]); stampa 2 volte lo stessoindirizzo.
I Possiamo far puntare un puntatore al primo elemento di un vettore.
int vet[5];int *pi;pi = vet; e equivalente a pi = &vet[0];
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 248
La programmazione nel linguaggio C Puntatori
Accesso agli elementi di un vettoreEsempio:int vet[5];int *pi = vet;*(pi + 3) = 28;
I pi+3 punta all’elemento di indice 3 del vettore (il quarto elemento).I 3 viene detto offset (o scostamento) del puntatore.I N.B. Servono le () perche * ha priorita maggiore di +. Che cosa
denota *pi + 3 ?I Osservazione:
&vet[3] equivale a pi+3 equivale a vet+3*&vet[3] equivale a *(pi+3) equivale a *(vet+3)
I Inoltre, *&vet[3] equivale a vet[3]I In C, vet[3] e semplicemente un modo alternativo di scrivere
*(vet+3).I Notazioni per gli elementi di un vettore:
I vet[3] =⇒ notazione con puntatore e indiceI *(vet+3) =⇒ notazione con puntatore e offset
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 249
La programmazione nel linguaggio C Puntatori
I Un esempio che riassume i modi in cui si puo accedere agli elementidi un vettore.
int vet[5] = {11, 22, 33, 44, 55};int *pi = vet;int offset = 3;
/* assegnamenti equivalenti */
vet[offset] = 88;*(vet + offset) = 88;pi[offset] = 88;*(pi + offset) = 88;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 250
La programmazione nel linguaggio C Puntatori
I Attenzione: a differenza di un normale puntatore, il nome di unvettore e un puntatore costante
I il suo valore non puo essere modificato!
I int vet[10];int *pi;
pi = vet; corretto
pi++; corretto
vet++; scorretto: vet e’ un puntatore costante!
I E questo il vero motivo per cui non e possibile assegnare un vettoread un altro utilizzando i loro nomi
int a[3]={1,1,1}, b[3] i;for (i=0; i<3; i++)
b[i] = a[i];
ma non b=a (b e un puntatore costante!)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 251
La programmazione nel linguaggio C Puntatori
Modi alternativi per scandire un vettore
int a[LUNG]= {.......};int i, *p=a;
I I seguenti sono tutti modi equivalenti per stampare i valori di a
for (i=0; i<LUNG; i++) for (i=0; i<LUNG; i++)
printf("%d", a[i]); printf("%d", p[i]);
for (i=0; i<LUNG; i++) for (i=0; i<LUNG; i++)
printf("%d", *(a+i)); printf("%d", *(p+i));
for (p=a; p<a+LUNG; p++)
printf("%d", *p);
I Non e invece lecito un ciclo del tipofor ( ; a<p+LUNG; a++)
printf("%d", *a);perche? Perche a++ e un assegnamento sul puntatore costante a!.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 252
La programmazione nel linguaggio C Puntatori
Differenza tra puntatori
I Il parallelo tra vettori e puntatori ci consente di capire il senso diun’operazione del tipo p-q dove p e q sono puntatori allo stesso tipo.
int *p, *q;int a[10]={0};int x;...x=p-q;
I Il valore di x e il numero di interi compresi tra l’indirizzo p el’indirizzo q.
I Quindi se nel codice precedente ... sono le istruzioni:q = a;p = &a[5];
il valore di x dopo l’assegnamento e 5.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 253
La programmazione nel linguaggio C Puntatori
Esempio
double b[10] = {0.0};double *fp, *fq;char *cp, *cq;
fp = b+5;fq = b;
cp = (char *) (b+5);cq = (char *) b;
printf("fp=%p cp=%p fq=%p cq=%p\n", fp, cp, fq, cq);printf("fp-fq= %d, cp-cq=%d\n", fp-fq, cp-cq);
fp=0x22fe3c cp=0x22fe3c fq=0x22fe14 cq=0x22fe14fp-fq=5 cp-cq=40
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 254
La programmazione nel linguaggio C Funzioni
Modularizzazione
I Quando abbiamo a che fare con un problema complesso spesso losuddividiamo in problemi piu semplici che risolviamo separatamente,per poi combinare insieme le soluzioni dei sottoproblemi al fine dideterminare la soluzione del problema di partenza.
I Esempio: La moltiplicazione di numeri con molte cifre vienesuddivisa in moltiplicazioni cifra per cifra e i risultati di queste ultimevengono combinate insieme mediante addizioni.
I Questo procedimento e applicabile anche alla programmazione.
I si suddivide un problema complesso in problemi di volta in volta piusemplici
I una volta individuati (sotto)problemi sufficientemente elementari sirisolvono questi ultimi direttamente
I si combinano le soluzioni dei sottoproblemi per ottenere la soluzionedel problema di partenza
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 255
La programmazione nel linguaggio C Funzioni
I Approccio top-down: si parte dall’alto, considerando il problema nellasua interezza e si procede verso il basso per raffinamenti successivifino a ridurlo ad un insieme di sottoproblemi elementari
I Approccio bottom-up: ci si occupa prima di risolvere singole parti delproblema, senza averne necessariamente una visione d’insieme, perpoi risalire procedendo per aggiustamenti successivi fino ad ottenerela soluzione globale.
I I linguaggi di programmazione mettono a disposizione dei meccanismidi astrazione che favoriscono un approccio modulareAstrazione sui dati - il programmatore puo definire nuovi tipi didato specifici per il particolare problema (tipi di dato astratti)
I collezioni di valoriI operazioni con le quali operare su tali valori
Astrazione funzionale - il programmatore puo estendere lefunzionalita del linguaggio definendo sottoprogrammi che risolvono(sotto)problemi specifici.
I i sottoprogrammi sono di solito parametriciI possono essere (ri)usati alla stessa stregua delle operazioni built-in del
linguaggio
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 256
La programmazione nel linguaggio C Funzioni
FunzioniI In C i sottoprogrammi si realizzano attraverso le funzioni.I Una funzione puo essere vista come una scatola nera:
parametri di ingresso −→ F −→ valore calcolato
• risolve un sottoproblema specifico• attraverso i parametri e il risultato scambia informazioni con il main e
con altre funzioni
Esempio:
x −→ abs −→ | x |
x , y −→ mcd −→ mcd(x , y)
b, e −→ exp −→ be
x1, . . . , xn −→ sum −→n∑
i=1xi
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 257
La programmazione nel linguaggio C Funzioni
Esempio: Definizione di abs in Cint abs(int x){int ris;if (x<0)
ris = -x;else
ris = x;return ris; }
I Uso della funzionemain(){int x1, x2, z, w;
...z = abs(x1);...
printf("%d\n", w + abs(x2));...
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 258
La programmazione nel linguaggio C Funzioni
I Il linguaggio deve mettere a disposizione strumenti perI definire nuove operazioni astratte (funzioni)I usare le nuove operazioni definite
I Distinguiamo due momenti diversi:I la definizione della funzione
definisce il codice che realizza l’operazione astrattaI e la chiamata della funzione
corrisponde all’utilizzo della funzione
I Ad una stessa definizione possono corrispondere diverse chiamate(come z = abs(x1) e w + abs(x2) nell’esempio precedente).
I Nella definizione della funzione, il codice fa riferimento agli argomentio parametri formali della funzione (nell’esempio x)
=⇒ un parametro formale non corrisponde ad un valore vero eproprio: e semplicemente un riferimento simbolico (ad un argomentodella funzione)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 259
La programmazione nel linguaggio C Funzioni
Esempio:
int exp(int base, int esponente){int ris = 1;while (esponente > 0)
{ris = ris * base;esponente = esponente - 1;
}return ris;}
I I parametri formali sono base ed esponente
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 260
La programmazione nel linguaggio C Funzioni
I Al momento della chiamata, alla funzione vengono forniti i valori degliargomenti, o parametri attuali, rispetto ai quali effettuare il calcolo
int exp(int base, int esponente){...}
main() {int b, e, r1, r2;
...r1 = exp(2,5);...
scanf("%d %d", &b, &e);r2 = exp(b, e);... }
I Prima chiamata exp(2,5)I 2 e il parametro attuale corrispondente a baseI 5 e il parametro attuale corrispondente a esponente
I Seconda chiamata exp(b,e)I b e il parametro attuale corrispondente a baseI e e il parametro attuale corrispondente a esponente
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 261
La programmazione nel linguaggio C Funzioni
Funzioni: definizione
Sintassi:intestazione blocco
doveI blocco e il corpo della funzioneI intestazione e l’intestazione della funzione ed ha la seguente forma:
id-tipo identificatore (parametri-formali)
I id-tipo specifica il tipo del risultato calcolato dalla funzioneI identificatore specifica il nome della funzione ed e un qualsiasi
identificatore C validoI parametri-formali e una sequenza (eventualmente vuota) di
dichiarazioni di parametro (tipo e nome) separate da virgola
Esempi: intestazioni di funzioneI int abs (int x)
int MassimoComunDivisore(int a, int b)I double Potenza(double x, double y)
float media (int vet[], int lung)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 262
La programmazione nel linguaggio C Funzioni
Funzioni: chiamata (invocazione, attivazione)
Sintassi:identificatore (parametri-attuali)
I identificatore e il nome della funzioneI lista-parametri-attuali e una lista di espressioni separate da
virgolaI i parametri attuali devono corrispondere in numero e tipo ai parametri
formali
Esempi: chiamate di funzioni
int mcd, x, y1, y2;double exp, w, v, z;
...mcd = MassimoComunDivisore(x+1, y1+y2);exp = Potenza(z, 3.0);...
exp = Potenza(z, Potenza(v,w));
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 263
La programmazione nel linguaggio C Funzioni
Semantica (informale) di una chiamata di funzione
I Dentro il corpo di una funzione F compare una chiamata di un’altrafunzione G
I F viene detta funzione chiamanteI G viene detta funzione chiamata
Esempio: nel main c’e un assegnamento x = abs(x);=⇒ main e il chiamante, abs il chiamato
I Una chiamata di funzione e un’espressione, la cui valutazione avvienecome segue:
I viene sospesa l’esecuzione di F e viene “ceduto il controllo” a G, dopoaver opportunamente associato i parametri attuali ai parametri formali(passaggio dei parametri, fra poco . . . )
I vengono eseguite le istruzioni di G, a partire dalla primaI l’esecuzione di G termina con l’esecuzione di un’istruzione speciale
(istruzione return) che calcola il risultato della chiamata (e il valoredell’espressione corrispondente alla chiamata)
I al termine dell’esecuzione di G il controllo ritorna a F, che proseguel’esecuzione a partire dal punto in cui G era stata attivata
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 264
La programmazione nel linguaggio C Funzioni
Valore di ritorno di una funzione: istruzione returnI Esempio: Funzione che restituisce il massimo tra due interi.
int max(int m, int n) {if (m >= n)return m;
elsereturn n; }
I Chiamata di max, ad esempio da main:
main() {int i, j, massimo;scanf("%d%d", &i, &j);massimo = max(i,j);printf("massimo = %d\n", massimo); }
I La funzione main tramite i parametri attuali comunica alla funzionemax i valori sui quali calcolare la funzione (il valore delle variabili i,j).
I La funzione max tramite il valore di ritorno comunica il risultato almain.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 265
La programmazione nel linguaggio C Funzioni
I Nel corpo deve esserci l’istruzione return espressione; la cuiesecuzione comporta:
I il calcolo del valore di espressione: questo valore viene restituito alchiamante come risultato dell’esecuzione della funzione
I la cessione del controllo alla funzione chiamante
Osservazioni
I in return espressione, il tipo di espressione deve essere lo stessodel tipo del risultato della funzione dichiarato nella definizione
I l’esecuzione di return espressione comporta la terminazionedell’esecuzione della funzioneEsempio:
int max(int m, int n) {if (m >= n)return m;
elsereturn n;
printf("pippo"); /* non viene mai eseguita */ }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 266
La programmazione nel linguaggio C Funzioni
Dichiarazioni di funzione (o prototipi)I I parametri attuali nella chiamata di una funzione devono
corrispondere in numero e tipo (in ordine) ai parametri formali.I Dobbiamo permettere al compilatore di fare questo controllo
=⇒ prima della chiamata deve essere nota l’intestazioneI Due possibilita:
1. la funzione e stata definita prima2. la funzione e stata dichiarata prima
Sintassi della dichiarazione di funzione (o prototipo)
intestazione; ovvero:id-tipo identificatore (parametri-formali);
I c’e‘ un “;” finale al posto del bloccoI nella lista di parametri formali puo anche mancare il nome dei
parametri — interessa solo il tipoI il compilatore usa la dichiarazione per controllare che l’attivazione sia
correttaI dopo deve esserci una definizione della funzione coerente con la
dichiarazione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 267
La programmazione nel linguaggio C Funzioni
Ordine di dichiarazioni e funzioni
I Bisogna dichiarare o definire ogni funzione prima di usarla (chiamarla)
I E pratica comune specificare in quest’ordine:
1. dichiarazioni (prototipi) di tutte le funzioni (tranne main)2. definizione di main3. definizioni delle funzioni
I In questo modo ogni funzione e stata dichiarata prima di essere usata
I L’ordine in cui mettiamo le definizioni non deve necessariamentecorrispondere a quello delle dichiarazioni.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 268
La programmazione nel linguaggio C Funzioni
Esempio:int max(int, int);
int foo(char, int);
main() ...
int max(int m, int n) ... /* OK. definizione coerentecon il prototipo */
int foo (int z, char c) ... /* NO! definizione non coerentecon il prototipo */
Nella definzione di foo i parametri formali non sono nell’ordine specificato dalprototipo.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 269
La programmazione nel linguaggio C Funzioni
Passaggio dei parametri
I Abbiamo visto che le funzioni utilizzano parametri
I permettono uno scambio di dati tra chiamante e chiamatoI nell’intestazione/prototipo: lista di parametri formali (con tipo
associato) – sono delle variabiliI nell’attivazione: lista di parametri attuali — possono essere delle
espressioni
I Al momento della chiamata ogni parametro formale viene inizializzatoal valore del corrispondente parametro attuale.
I Il valore del parametro attuale viene copiato nella locazione dimemoria del corrispondente parametro formale.
I Questo meccanismo di passaggio dei parametri viene comunementedetto passaggio per valore.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 270
La programmazione nel linguaggio C Funzioni
Esempio:
int succ (int); /* prototipo di succ */
main() int succ (int x){ int z, w; { x = x + 1;
z = 10; return x;w = succ(z); }printf("%d", w);
}
I L’effetto della chiamata succ(z) puo essere simulato dall’esecuzionedella seguente porzione di codice:
x = 10; /* il parametro formale viene inizializzato conil valore del parametro attuale */
x = x + 1; /* esecuzione del corpo della funzionereturn x; succ */
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 271
La programmazione nel linguaggio C Funzioni
I Chiamate diverse corrispondono ad inizializzazioni diverse dellevariabili corrispondenti ai parametri formali
w = succ(20); x = 20;=⇒ x = x + 1;
return x;
I In questo caso il valore assegnato alla variabile w e 21.
z = 10;w = succ(z+3); x = 13;
=⇒ x = x + 1;return x;
I In questo caso il valore assegnato alla variabile w e 14.
I Se non vi e corrispondenza perfetta tra il tipo del parametro formale equello del parametro attuale, viene effettuata una conversione implicitadi tipo secondo le regole gia viste.
I Il passaggio dei parametri di tipo array non comporta la copia dei valoridell’array (fra poco ...)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 272
La programmazione nel linguaggio C Funzioni
Procedure
I Non sempre le operazioni astratte di cui abbiamo bisogno possonoessere descritte in modo naturale come funzioni matematiche.
Esempio: progettare un’interfaccia utente per la stampa di figuregeometriche, in cui l’utente puo scegliere:
1. la forma della figura2. la dimensione3. il carattere di riempimento4. . . .
I In questo caso il compito dell’operazione astratta non e (o non esoltanto) produrre un valore, ma e produrre effetti di altro tipo,tipicamente modifiche di stato.
=⇒ in questi casi possiamo utilizzare procedureI le procedure sono un’astrazione delle istruzioniI le funzioni sono un’astrazione degli operatori
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 273
La programmazione nel linguaggio C Funzioni
Le procedure in C
I Una procedura e una funzione avente come tipo del risultato il tipospeciale void.
I La definizione/dichiarazione di procedure e la loro chiamata e analogaal caso delle funzioni
Esempio:void emoticon (int n)
{ /* stampa n volte la sequenza -:) */
int i;
for (i=0; i<n; i++)
{putchar(’-’); putchar(’:’); putchar(’)’); putchar(’ ’);}
}
main() {
...;
emoticon(3);
... }
I Le procedure non contengono di solito un’istruzione return (se lacontengono e del tipo return; che non comporta il calcolo di alcunvalore, ma solo la cessione del controllo al chiamante)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 274
La programmazione nel linguaggio C Funzioni
I La semantica di una chiamata di procedura P da unafunzione/procedura F e analoga a quella della chiamata di funzione,ma una chiamata di procedura e un’istruzione
I In particolare, il passaggio dei parametri avviene per valore come nelcaso delle funzioni
I il controllo viene restituito al chiamante al termine dell’esecuzione delblocco che costituisce il corpo della procedura (o in corrispondenzadell’esecuzione di un’istruzione del tipo return;)
I Il C non distingue tra funzioni e procedure (queste ultime sono casiparticolari di funzioni)=⇒ concettualmente, pero, e bene vedere le funzioni come astrazionidi operazioni e le procedure come astrazioni di istruzioni.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 275
La programmazione nel linguaggio C Funzioni
Esempio:Procedura che stampa una cornice di asterischi di “altezza” parametrica
void stampaCornice(int altezza){int i;printf("*********************\n");for (i=1; i<=altezza; i++)
printf("* *\n");printf("*********************\n");return;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 276
La programmazione nel linguaggio C Funzioni
I Come astrazione delle istruzioni, le procedure possono dovermodificare lo stato.Esempio: Procedura abs che assegna ad una variabile intera il suovalore assoluto
I il chiamante deve comunicare alla procedura la variabile in questioneI la procedura deve analizzare il valore della variabile e, se necessario,
effettuare il rimpiazzamento
I La seguente realizzazione della procedura non e corretta
void abs(int x){ if (x < 0)
x = -x; }I Simuliamo il comportamento di una chiamata della procedura (come
visto in precedenza)int z = -5;abs(z); =⇒ x = -5;
if (x < 0) x = -x;I La modifica del parametro formale non si ripercuote sul parametro
attuale (si ricordi che il passaggio dei parametri e per valore).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 277
La programmazione nel linguaggio C Funzioni
Passaggio dei parametri per indirizzoI Per ottenere l’effetto di modificare il valore dei parametri attuali,
alcuni linguaggi (es. Pascal) prevedono un’ulteriore modalita dipassaggio dei parametri, il passaggio per indirizzo
I informalmente: il passaggio per indirizzo fa in modo che, al momentodella chiamata, il parametro formale costituisca un modo alternativoper accedere al parametro attuale (che deve essere una variabile e nonpuo essere una generica espressione)
I durante l’esecuzione del corpo, ogni riferimento (e in particolaremodifica) al parametro formale e di fatto un riferimento al parametroattuale.
I In C esiste solo il passaggio per valore, ma quello per indirizzo si puorealizzare come segue:
1. si utilizza un parametro formale di tipo puntatore2. all’interno del corpo della procedura ogni riferimento al parametro
formale avviene attraverso l’operatore di dereferenziazione *3. al momento della chiamata, si utilizza come parametro attuale un
indirizzo di una variabile (utilizzando, se necessario, l’operatore diindirizzo &).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 278
La programmazione nel linguaggio C Funzioni
Esempio: Riprendiamo l’esempio del valore assoluto.
void abs(int *x){if (*x < 0)*x = -(*x);
}I Nel chiamante si utilizzano chiamate del tipo abs(&z) per ottenere
l’effetto di rimpiazzare il valore della variabile z con il suo valoreassoluto.int z = -5;abs(&z); =⇒ x = &z;
if (*x < 0) *x = -(*x);I N.B. Il passaggio dei parametri e sempre per valore, ma questa volta
viene passato un valore puntatore che consente di accedere allavariabile del chiamante.
I Nell’esempio, l’assegnamento *x = -(*x); ha come effetto lamodifica della variabile z del chiamante, in quanto il valore di x e &ze dunque *x e proprio z.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 279
La programmazione nel linguaggio C Funzioni
Esempio: Procedura per lo scambio di due variabili intere
void swap(int *x, int *y){int temp = *x;*x = *y;*y = temp;
}I Esempio di utilizzo: programma che legge due valori interi e li stampa
ordinati.
main() {int a, b;scanf("%d", &a);scanf("%d", &b);if (a > b) swap(&a, &b);printf("Valore minimo: %d\n", a);printf("Valore massimo: %d\n", b); }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 280
La programmazione nel linguaggio C Funzioni
Parametri di tipo vettoreI Il meccanismo del passaggio per valore di un indirizzo consente il
passaggio di vettori come parametri di funzioni/procedure.I Quando si passa un vettore come parametro ad una funzione, in
realta si sta passando l’indirizzo dell’elemento di indice 0.I Il parametro formale deve essere di tipo puntatore (al tipo degli
elementi del vettore)I di solito si passa anche la dimensione del vettore in un ulteriore
parametro.
Esempio:void stampaVettore(int *v, int dim)
{ int i;
for (i = 0; i < dim; i++)
printf("v[%d]: %d\n", i, v[i]);
}
main()
{ int vet[5] = {1, 2, 3, 4, 5};
...
stampaVettore(vet, 5); ... }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 281
La programmazione nel linguaggio C Funzioni
I Per evidenziare che il parametro formale e un vettore (ovverol’indirizzo dell’elemento di indice 0), si puo utilizzare la notazionenome-parametro[] invece di *nome-parametro.Esempio: void stampa(int v[], int dim) { ... }
I Si puo anche specificare la dimensione nel parametro, ma questaviene ignorata.
Esempio: void stampa(int v[5], int dim) { ... }I Come al solito, nel prototipo della funzione il nome del parametro
(vettore) puo anche mancare.
Esempio: void stampa(int [], int);
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 282
La programmazione nel linguaggio C Funzioni
I Il passaggio di un vettore e un passaggio per indirizzo.
=⇒ La funzione puo modificare gli elementi del vettore passato.
Esempio: Lettura di un vettore.
void leggiVettore(int v[], int dim){int i;for (i = 0; i < dim; i++){
printf("Immettere l’elemento di indice %d: ", i);scanf("%d", &v[i]);
}}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 283
La programmazione nel linguaggio C Funzioni
Esempio: Programma che legge, inverte e stampa un vettore di interi
#include <stdio.h>
#define LUNG 5
void leggiVettore(int [], int);
void stampaVettore(int [], int);
void invertiVettore(int [], int);
main()
{
int vett[LUNG];
leggiVettore(vett, LUNG);
printf("Vettore prima dell’inversione\n");
stampaVettore(vett, LUNG);
invertiVettore(vett, LUNG);
printf("Vettore dopo l’inversione\n");
stampaVettore(vett, LUNG);
}
I La definizione della proceduravoid invertiVettore(int [], int); e lasciata per esercizio.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 284
La programmazione nel linguaggio C Funzioni
Passaggio di matrici come parametriI Quando passiamo un vettore ad una funzione, passiamo in realta il
puntatore (costante) all’elemento di indice 0.
=⇒ non serve specificare la dimensione del vettore nel parametro formale.
I Quando passiamo una matrice ad una funzione, per poter accederecorrettamente agli elementi, la funzione deve conoscere il numero dicolonne della matrice.
=⇒ Non possiamo specificare il parametro nella forma mat[][], come per i
vettori, ma dobbiamo specificare il numero di colonne.
Esempio: void stampa(int mat[][5], int righe) { ... }I Il motivo e semplice: per accedere ad un generico elemento della
matrice, mat[i][j], la funzione deve calcolare l’indirizzo di taleelemento mat + offset. Per calcolare correttamente offset enecessario sapere quante sono le colonne.
I L’indirizzo di mat[i][j] e infatti:mat + (i · C · sizeof(int)) + (j · sizeof(int))
dove C e il numero di colonne (ovvero gli elementi in ciascuna riga).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 285
La programmazione nel linguaggio C Funzioni
Riassumendo:I per calcolare l’indirizzo dell’elemento mat[i][j] e necessario
conoscere:I il valore di mat, ovvero l’indirizzo del primo elemento della matriceI l’indice di riga i dell’elementoI l’indice di colonna j dell’elementoI il numero C di colonne della matrice
I In generale, in un parametro di tipo array vanno specificate tutte ledimensioni, tranne eventualmente la prima.
1. vettore: non serve specificare il numero di elementi2. matrice: bisogna specificare il numero di colonne, ma non serve il
numero di righe
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 286
La programmazione nel linguaggio C Funzioni
EsercizioDefinire le funzioni/procedure utilizzate nel seguente programma e completarecon gli opportuni parametri attuali la chiamata di swap in modo che il suo effettosia di scambiare gli elementi minimo e massimo del vettore.
#include <stdio.h>
#define LUNG 10
void leggivet (int [] vet, int dim);
void stampavet (int [] vet, int dim);
int indice_minimo (int vet[], int dim);
int indice_massimo (int vet[], int dim);
void swap (int *, int *);
main()
{
int vettore[LUNG], pos_min, pos_max;
leggivet(vettore, LUNG);
pos_min = indice_minimo(vettore, LUNG);
pos_max = indice_massimo(vettore, LUNG);
swap (?, ?); /* scambio degli elementi minimo e massimo */
printf("Vettore dopo lo scambio dell’elemento minimo e massimo:\n");
stampavet(vettore, LUNG);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 287
La programmazione nel linguaggio C Funzioni
Uso di funzioni e librerie di funzioniI Il meccanismo delle funzioni/procedure consente di modularizzare un
programma.
Esempio: Programma che stampa una tabella di potenze.
#include <stdio.h>
#define N 8
long potenza (int base, int esponente);
/* calcola base^esponente */
void intestazione();
/* stampa una intestazione */
void stampaTabellaPotenze(int m);
/* stampa la tabella di potenze i^j con i,j in [1,n]*/
/* utilizza la funzione potenza */
main() {
intestazione();
stampaTabellaPotenze(N);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 288
La programmazione nel linguaggio C Funzioni
Dopo la funzione main mettiamo le definizioni delle funzioni i cui prototipisono stati dichiarati nella parte dichiarativa.
long potenza (int base, int esponente)
/* calcola base^esponente */
{
int i;
long pot = 1;
for(i=1; i<=esponente; i++)
pot *= base;
return pot;
}
void intestazione()
{
printf("\n\n::::::::: TABELLA DI POTENZE :::::::::\n\n");
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 289
La programmazione nel linguaggio C Funzioni
void stampaTabellaPotenze(int m)
{
int i,j;
for (i=1; i<= m; i++)
{
for(j=1; j<=m; j++)
printf("%-10ld", potenza(i,j));
putchar(’\n’);
}
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 290
La programmazione nel linguaggio C Funzioni
Struttura tipica di un programma
I parte direttiva
#include <stdio.h>#define N 8
I parte dichiarativa che comprende:I dichiarazioni (prototipi) di funzioni/procedure
long potenza (int base, int esponente);void intestazione();void stampaTabellaPotenze(int m);
I altro ...
I il programma principale (main)
I le definizioni di funzioni/procedure
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 291
La programmazione nel linguaggio C Regole di visibilita
Variabili localiI Il blocco che costituisce il corpo di una funzione/procedura puo
contenere dichiarazioni di variabili.
Esempio:
void leggiVettore(int v[], int dim){int i; /* i E’ UNA VARIABILE LOCALE */for (i = 0; i < dim; i++) { ... }
}
I sono variabili proprie della funzioneI hanno tempo di vita limitato alla durata della chiamataI piu in generale: un identificatore dichiarato nel corpo di una funzione e
detto locale alla funzione e non e visibile all’esterno della funzione (adesempio nel main), ma solo nel corpo della stessa
I In realta, cio non e altro che un caso particolare di regole generali chegovernano la visibilita e il tempo di vita degli identificatori di unprogramma.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 288
La programmazione nel linguaggio C Regole di visibilita
Struttura generale di un programma C
I parte direttivaI parte dichiarativa globale che comprende:
I dichiarazioni di costantiI dichiarazioni di tipi (li vedremo . . . )I dichiarazioni di variabili (variabili globali)I prototipi di funzioni/procedure
I il programma principale (main)
I le definizioni di funzioni/procedure
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 289
La programmazione nel linguaggio C Regole di visibilita
Esempio
#include <stdio.h> /* parte direttiva */
#define LUNG 10
int i = 1; /* variabili globali */
int j = 2;
int Q(int); /* prototipi di funzioni e procedure */
void P(int *);
main() /* programma principale */
{
int x = 10;
char c = ’a’;
x = Q(x);
P(&x);
}
int Q(int v) { ... } /* definizioni di funzioni e procedure */
void P(int *z) { ... }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 290
La programmazione nel linguaggio C Regole di visibilita
BlocchiI il corpo di una funzione/procedura, cosi’ come il corpo del
programma principale, e un blocco.I In C un blocco e costituito da
I una parte dichiarativa (puo non esserci)I una parte esecutiva (sequenza di istruzioni)
I Nel main o nel corpo delle funzioni possono comparire diversi blocchi,che possono essere
I annidati: un blocco e una delle istruzioni di un altro bloccoI paralleli: blocchi che fanno parte della medesima sequenza di istruzioni{ {
int x; int x;
x = 10; x = 10;
{ ...
int z; }
z = 20 ; {
... int z;
} z = 20;
... ...
} }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 291
La programmazione nel linguaggio C Regole di visibilita
I Anche la parte esecutiva del programma principale e di unafunzione/procedura e un blocco
I Gli identificatori dichiarati nella parte dichiarativa di un blocco sonodetti nomi locali del blocco e devono essere tutti diversi tra loro
I nel caso di una funzione/procedura, fanno parte dei nomi locali anchegli identificatori utilizzati per i parametri formali
Esempio:
{
int x; /* NO! identificatore x dichiarato */
char x; /* due volte nello stesso blocco */
...
}
void p(int x, char y)
{
int x; /* NO! identificatore x gia’ usato per un parametro formale */
...
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 292
La programmazione nel linguaggio C Regole di visibilita
I In blocchi diversi possono essere utilizzati gli stessi identificatori
Esempio:
main()
{
int x; /* x, y: variabili locali del main */
int y;
...
{
char x; /* x: variabile locale del blocco annidato */
...
}
...
}
void p(int x)
{
int y; /*x,y: variabili locali della procedura p */
...
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 293
La programmazione nel linguaggio C Regole di visibilita
I Un programma C puo avere una struttura molto complessa a seguitodell’uso di funzioni, procedure e blocchi.
I E necessario definire regole precise per regolamentare l’uso dei nomiutilizzati all’interno di un programma.
I A questo scopo introduciamo alcune definizioni utili.Ambiente globale: e l’insieme di tutti gli elementi (nomi) dichiaratinella parte dichiarativa globale del programmaAmbiente locale di una funzione: e l’insieme di tutti gli elementi (nomi)dichiarati nella parte dichiarativa della funzione e nella sua intestazioneAmbiente locale di un blocco: e l’insieme di tutti gli elementi (nomi)dichiarati nella parte dichiarativa del blocco
I Quanto detto informalmente in precedenza puo essere meglioprecisato:
=⇒ e possibile dichiarare piu volte lo stesso identificatore (anche consignificati diversi) purche in ambienti diversi
I Se cio evita il proliferare di identificatori, causa il problema di stabilireil significato di un riferimento ad un identificatore in un genericopunto del programma
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 294
La programmazione nel linguaggio C Regole di visibilita
Esempio: Riprendiamo l’esempio precedentemain()
{
int x; /* x, y: variabili locali del main */
int y;
...
{
char x; /* x: variabile locale del blocco annidato */
...
}
...
}
void p(int x)
{
int y; /*x,y: variabili locali della procedura p */
...
}
I Se in un punto del programma viene eseguita l’istruzione x = ..., aquale delle tre dichiarazioni di x ci si riferisce?
I Dipende dal punto in cui si trova tale assegnamento e dalle regole divisibilita (o regole di scoping).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 295
La programmazione nel linguaggio C Regole di visibilita
Regole di visibilitaI Gli identificatori presenti nell’ambiente globale sono visibili in tutte le
funzioni e in tutti i blocchi del programma.Se un identificatore e definito in piu punti (in blocchi e/o funzioni), ladefinizione valida e quella dell’ambiente piu vicino al punto di utlizzo.N.B. Gli identificatori predefiniti del linguaggio si intendono partedell’ambiente globale.
I Gli identificatori presenti nell’ambiente locale di una funzione sonovisibili nel corpo della funzione (ivi compresi eventuali blocchi in essocontenuti).Se un identificatore e definito in piu punti del corpo, la definizionevalida e quella dell’ambiente piu vicino al punto di utlizzo.
I Gli identificatori presenti nell’ambiente locale di un blocco sonovisibili nella parte esecutiva del blocco (ivi compresi eventuali blocchiin essa contenuti).Se un identificatore e definito in piu punti di un blocco, la definizionevalida e quella dell’ambiente piu vicino al punto di utlizzo.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 296
La programmazione nel linguaggio C Regole di visibilita
I Detto altrimenti, l’ambito di visibilita di un identificatore edeterminato dalla posizione della sua dichiarazione:
I gli identificatori dichiarati all’interno di un blocco hanno ambito divisibilita a livello di blocco=⇒ una variabile dichiarata in un blocco e visibile solo in quel blocco(compresi eventuali blocchi annidati)
I gli identificatori dichiarati all’interno di una funzione (compresi quellinell’intestazione) hanno ambito di visibilita a livello di funzione=⇒ una variabile dichiarata in una funzione e visibile solo nel corpodella funzione (compresi eventuali blocchi annidati)
I gli identificatori dichiarati all’esterno delle funzioni e del main hannoambito di visibilita a livello di programma=⇒ una variabile globale e visibile ovunque nel programma
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 297
La programmazione nel linguaggio C Regole di visibilita
Esempio:
int x1=10, x2=20;
char c=’a’;
int f(int);
main()
{
int x1=30; /* nasconde la variabile globale x1 */
x2 = x1+x2; /* x1 e’ quella locale, x2 e’ globale */
printf("x1=%d x2=%d\n", x1, x2); /* stampa x1=30 x2=50 */
{ int x3=50;
x1=f(x3); /* x1 e’ quella locale al primo blocco */
printf("x1=%d x2=%d\n", x1, x2); /* stampa x1=150 x2=50 */
}
}
int f(int x1) /* nasconde la variabile globale x1 */
{ int x2; /* nasconde la variabile globale x2 */
x2 = x1 + 100; /* x1 e’ il parametro formale, x2 la var. locale */
return x2;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 298
La programmazione nel linguaggio C Regole di visibilita
Rappresentazione Grafica: Modello a contorniI Si rappresenta ogni ambiente mediante un rettangolo con gli
identificatori in esso contenuti.
x1, x2, c globali
x1 main
x1, x2 f
x3blocco
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 299
La programmazione nel linguaggio C Durata delle variabili
Durata delle variabiliI Una variabile ha un suo tempo di vita.
• viene creata (ovvero ad essa viene riservata uno spazio di memoria)• viene (o puo essere) distrutta (ovvero viene rilasciato ilcorrispondente spazio di memoria).
I Si distinguono due classi di variabili:I variabili automatiche: vengono create ogni volta che si entra nel loro
ambiente di visibilita e vengono distrutte all’uscita di tale ambienteI es. variabili locali di un blocco: vengono create all’ingresso del blocco {
distrutte all’uscita dal blocco }I es. variabili locali di una funzione: vengono create al momento della
chiamata e distrutte all’uscita
I variabili statiche: vengono create una sola volta e vengono distruttesolo al termine dell’esecuzione del programma (non ne faremo uso ...)
I N.B. nel caso di funzioni/blocchi eseguiti piu volte (es. funzionechiamata in punti diversi, blocco all’interno di un ciclo):
le variabili automatiche corrispondenti possono essere associate di voltain volta a locazioni di memoria diverse, quindiil loro valore non persiste tra una esecuzione e la successiva
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 300
La programmazione nel linguaggio C Durata delle variabili
Gestione della memoria a tempo di esecuzione (run-time)I Il codice macchina e i dati risiedono entrambi in memoria, ma in zone
separate:I la memoria per il codice macchina e fissata a tempo di compilazioneI la memoria per i dati (in particolare per le variabili automatiche) cresce
e decresce dinamicamente durante l’esecuzione: viene gestita a pilaI Una pila (o stack) e una struttura dati con accesso LIFO: Last In
First Out = l’ultimo entrato e il primo ad uscire (es.: pila di piatti dalavare).
I Il sistema gestisce in memoria la pila dei record di attivazione (RDA)I per ogni chiamata di funzione viene creato un nuovo RDA in cima alla
pilaI al termine della chiamata della funzione il RDA viene rimosso dalla pila
I Ogni RDA contiene:I le locazioni di memoria per i parametri formali (se presenti)I le locazioni di memoria per le variabili locali (se presenti)I altre informazioni che non analizziamo
I Anche gli ambienti locali dei blocchi vengono allocati/deallocati sullapila.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 301
La programmazione nel linguaggio C Durata delle variabili
Esempio:int f(int);
main()
{int x, y, z;
x=10;
y=20; /* blocco principale */ PUNTO 1
z = f(x); /* prima chiamata di f */ PUNTO 2
{int x=50; /* uscita da f e ingresso nel blocco annidato*/ PUNTO 3
y=f(x); /* seconda chiamata di f */ PUNTO 4
z=y; /* uscita da f */ PUNTO 5
}... /* uscita dal blocco */ PUNTO 6
}int f(int a)
{int z;
z = a + 1;
return z;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 302
La programmazione nel linguaggio C Durata delle variabili
Evoluzione della pila
x 10y 20z ?
PUNTO 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 303
La programmazione nel linguaggio C Durata delle variabili
Evoluzione della pila
a 10z ?
x 10y 20z ?
PUNTO 2
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 304
La programmazione nel linguaggio C Durata delle variabili
Evoluzione della pila
x 50
x 10y 20z 11
PUNTO 3
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 305
La programmazione nel linguaggio C Durata delle variabili
Evoluzione della pila
a 50z ?
x 50
x 10y 20z 11
PUNTO 4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 306
La programmazione nel linguaggio C Durata delle variabili
Evoluzione della pila
x 50
x 10y 51z 11
PUNTO 5
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 307
La programmazione nel linguaggio C Durata delle variabili
Evoluzione della pila
x 10y 51z 51
PUNTO 6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 308
La programmazione nel linguaggio C Durata delle variabili
Variabili statiche: un esempio d’uso
I Una variabile statica, una volta creata, rimane in vita per tutto iltempo di esecuzione del programma.Esempio: f(void) { static int x; ... }
I la variabile viene inizializzata alla prima attivazione della funzioneI conserva il suo valore tra attivazioni successiveI e locale, quindi visibile solo all’interno della funzione in cui e dichiarata
Esempio: Funzione che ritorna il numero di volte che e stataattivata.
int fun1(void) {static int conta = 0;
/* variabile locale statica visibile solo in fun1;contatore del numero di attivazioni di fun1 */
.....conta++;return conta;}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 309
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Programmazione ricorsiva: cenni
I In quasi tutti i linguaggi di programmazione evoluti e ammessa lapossibilita di definire funzioni/procedure ricorsive: durantel’esecuzione di una funzione F e possibile chiamare la funzione Fstessa.
I Cio puo avvenire
I direttamente: il corpo di F contiene una chiamata a F stessa.I indirettamente: F contiene una chiamata a G che a sua volta contiene
una chiamata a F.
I Questo puo sembrare strano: se pensiamo che una funzione edestinata a risolvere un sottoproblema P, una definizione ricorsivasembra indicare che per risolvere P dobbiamo . . . saper risolvere P!
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 310
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
I In realta, la programmazione ricorsiva si basa sull’osservazione cheper molti problemi la soluzione per un caso generico puo esserericavata sulla base della soluzione di un altro caso, generalmente piusemplice, dello stesso problema.
I La programmazione ricorsiva trova radici teoriche nel principio diinduzione ben fondata che puo essere visto come una generalizzazionedel principio di induzione sui naturali
I La soluzione di un problema viene individuata supponendo di saperlorisolvere su casi piu semplici.
I Bisogna poi essere in grado di risolvere direttamente il problema suicasi piu semplici di qualunque altro.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 311
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Esempio: Torre di Hanoi (leggenda Vietnamita).
A B C
I pila di dischi di dimensione decrescente su un perno A
I vogliamo spostarla sul perno C, usando un perno di appoggio BI vincoli:
I possiamo spostare un solo disco alla voltaI un disco piu grande non puo mai stare su un disco piu piccolo
I secondo la leggenda: i monaci stanno spostando 64 dischi:quando avranno finito, ci sara la fine del mondo
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 312
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
I Come individuare una soluzione per un numero N di dischi arbitrario?
I per N=1 la soluzione e immediata: spostiamo l’unico disco da A a CI se sappiamo risolvere il problema per N=1 lo sappiamo risolvere anche
per N=2: come?
A B CA B C
BA C A CB
I Notiamo l’utilizzo del perno ausiliario B
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 313
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
I Possiamo generalizzare il ragionamento? Se sappiamo risolvere ilproblema per N dischi, possiamo individuare una soluzione per lostesso problema ma con N+1 dischi?
BA C
CBAB
N
A C
N
A B C
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 314
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
I Formalizziamo il ragionamento
I Indichiamo con hanoi(N, P1, P2, P3) il problema:“spostare N dischidal perno P1 al perno P2 utilizzando P3 come perno d’appoggio”.
hanoi(N, P1, P2, P3)if (N=1)
sposta da P1 a P2;else{hanoi(N-1, P1, P3, P2);sposta da P1 a P2;hanoi(N-1, P3, P2, P1);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 315
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Esempio: Soluzione di hanoi(3,A,C,B)
hanoi(1,A,C,B) = sposta(A,C)hanoi(2,A,B,C) = sposta(A,B)
hanoi(1,C,B,A) = sposta(C,B)hanoi(3,A,C,B) = sposta(A, C)
hanoi(1,B,A,C) = sposta(B,A)hanoi(2,B,C,A) = sposta(B,C)
hanoi(1,A,C,B) = sposta(A,C)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 316
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
I Le funzioni ricorsive sono convenienti per implementare funzionimatematiche definite in modo induttivo.Esempio: Definizione induttiva di somma tra due interi nonnegativi:
somma(x , y) =
{x se y=0
1 + (somma(x , y − 1)) se y > 0
I La somma di x con 0 viene definita in modo immediato;I la somma di x con il successore di y viene definita come il successore
della somma tra x e y.
I Esempio: somma di 3 e 2:
somma(3, 2) = 1 + (somma(3, 1)) =
1 + (1 + (somma(3, 0))) =
1 + (1 + (3)) =1 + 4 =5
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 317
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Esempio: Funzione fattoriale.
I definizione iterativa: fatt(n) = n · (n − 1) · (n − 2) · · · 2 · 1I definizione induttiva:
fatt(n) =
{1 se n = 0 (caso base)
n · fatt(n − 1) se n > 0 (caso induttivo)
I E essenziale il fatto che, applicando ripetutamente il caso induttivo,ci riconduciamo prima o poi al caso base.
fatt(3) = 3 · fatt(2) =
3 · (2 · fatt(1)) =
3 · (2 · (1 · fatt(0))) =
3 · (2 · (1 · 1)) =3 · (2 · 1) =3 · 2 =6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 318
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Il codice delle due diverse versioniI definizione iterativa:
int fatt(int n) {int i,ris;
ris=1;for (i=1;i<=n;i++)
ris=ris*i;return ris;
}
I definizione ricorsiva:int fattric(int n) {
if (n == 0)return 1;
elsereturn n * fattric(n-1);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 319
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Esempio: Programma che usa una funzione ricorsiva.
#include <stdio.h>
int fattric (int);
main()
{
int x, f;
scanf("%d", &x);
f = fattric(x);
printf("Fattoriale di %d: %d\n", x, f);
}
int fattric(int n) {
int ris;
if (n == 0)
ris = 1;
else
ris = n * fattric(n-1);
return ris;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 320
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Evoluzione della pila (supponendo x=3).
x 3f ?
n 3ris ?
x 3f ?
n 2ris ?
n 3ris ?
x 3f ?
n 1ris ?
n 2ris ?
n 3ris ?
x 3f ?
n 0ris ?
n 1ris ?
n 2ris ?
n 3ris ?
x 3f ?
n 0ris 1
n 1ris ?
n 2ris ?
n 3ris ?
x 3f ?
n 1ris 1
n 2ris ?
n 3ris ?
x 3f ?
n 2ris 2
n 3ris ?
x 3f ?
n 3ris 6
x 3f ?
x 3f 6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 321
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
Esempio: Leggere una sequenza di caratteri terminata da ’\n’ estamparla invertita. Ad esempio: casa =⇒ asac
I Problema: prima di poter iniziare a stampare dobbiamo aver letto ememorizzato tutta la sequenza:
1. usando una struttura dati opportuna ma dinamica (liste, le vedremopiu avanti)
2. usando un procedimento ricorsivo.I leggiamo un carattere della sequenza, c1, leggiamo e stampiamo
ricorsivamente il resto della sequenza c2...cn e infine stampiamo c1;I il caso base e rappresentato dalla lettura del carattere di fine sequenza.
void invertInputRic()
{ char ch;
ch = getchar();
if (ch != ’\n’)
{
invertInputRic();
putchar(ch);
}
else
printf("Sequenza invertita: ");
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 322
La programmazione nel linguaggio C Programmazione ricorsiva: cenni
main()
{
printf("Immetti una sequenza di caratteri\n");
invertInputRic();
printf("\n");
}
Vediamo come evolve la pila per l’input ABC\nch A ch B
ch A
ch C
ch B
ch A
ch \nch C
ch B
ch A
ch C
ch B
ch A
ch B
ch A
ch A
L’output prodotto e il seguente
Sequenza invertita: CBA
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 323
La programmazione nel linguaggio C Tipi user-defined
Tipi user-defined
I Il C mette a disposizione un insieme di tipi di dato predefiniti (tipibuilt-in) e dei meccanismi per definire nuovi tipi (tipi user-defined)
I Vediamo le regole generali che governano la definizione di nuovi tipi equindi i costrutti linguistici (costruttori) che il C mette a disposizione.
I Tutti i tipi non predefiniti utilizzati in un programma devono esseredichiarati come ogni altro elemento del programma. Una dichiarazionedi tipo viene fatta di solito nella parte dichiarativa del programma.
I parte dichiarativa globale:I dichiarazioni di costantiI dichiarazioni di tipiI dichiarazioni di variabiliI prototipi di funzioni/procedure
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 335
La programmazione nel linguaggio C Tipi user-defined
Dichiarazione di tipoI Una dichiarazione di tipo (type declaration) consiste nella parola
chiave typedef seguita da:I la rappresentazione o costruzione del nuovo tipo (ovvero la specifica di
come e costruito a partire dai tipi gia esistenti)I il nome del nuovo tipoI il simbolo ; che chiude la dichiarazione
Esempio: typedef int anno;
I Una volta definito e nominato un nuovo tipo, e possibile utilizzarloper dichiarare nuovi oggetti (ad es. variabili) di quel tipo.
Esempio:float x;anno a;
I Nota: In C si possono anche definire tipi senza usare typedef.Quest’ultima consente l’associazione di un nome (identificatore) a unnuovo tipo. Per uniformita e leggibilita del codice useremo spessotypedef per definire nuovi tipi.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 336
La programmazione nel linguaggio C Tipi user-defined
Tipi semplici user-defined
Ridefinizione: Un nuovo tipo puo essere definito dandosemplicemente un nuovo nome a un tipo gia esistente
typedef TipoEsistente NuovoTipo;
dove TipoEsistente puo essere un tipo built-in o user-defined.
Esempio:typedef int anno;
typedef int naturale;
typedef char carattere;
Enumerazione: Consente di definire un nuovo tipo enumerando isuoi valori, con la seguente sintassi
typedef enum {v1, v2, ... , vk} NuovoTipo;
Esempio:typedef enum {lun, mar, mer, gio, ven, sab, dom} Giorno;
typedef enum {gen, feb, mar, apr, mag, giu,
lug, ago, set, ott, nov, dic} Mese;
typedef enum {m, f} sesso;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 337
La programmazione nel linguaggio C Tipi user-defined
I I valori elencati nella definizione di un nuovo tipo enumerato, sonoidentificatori che rappresentano costanti di quel tipo (esattamentecome 0, 1, 2, ... sono costanti del tipo int, o ’a’, ’b’, ...sono costanti del tipo char).
I Dunque, se dichiariamo una variabileGiorno g;possiamo scrivere l’assegnamentog = mar;
I Le costanti dei tipi enumerati non vanno racchiuse tra virgolette o traapici!
N.B. Il compilatore associa ai nomi utilizzati per denotare le costantidei tipi enumerati valori naturali progressivi.
Esempio: il valore associato a g dopo l’assegnamento g=mar e ilnumero naturale (intero) 1.
=⇒ mancanza di astrazione: e possibile fare riferimento allarappresentazione dei valori.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 338
La programmazione nel linguaggio C Tipi user-defined
I La relazione tra interi e tipi enumerati consente di applicare a questiultimi le seguenti operazioni:
I operazioni aritmetiche: +,-,*,/,%I uguaglianza e disuguaglianza: =, !=I confronto: <,<=,>,>=
I Si noti che la relazione di precedenza tra i valori (che determinal’esito delle operazioni di confronto) dipende dall’ordine in cuivengono elencati i valori del tipo al momento della sua definzione.
Esempio: Con le dichiarazioni viste in precedenzalun < gio e vero (un intero diverso da 0) apr <= feb e falso (ilvalore intero 0)
I Il costruttore di tipo enum consente di definire il tipo dei valori diverita (boolean) che e built-in in altri linguaggi.
typedef enum {false, true} boolean;
I Notare che i valori vanno elencati come sopra, rispettando laconvenzione adottata dal C secondo la quale il valore intero 0rappresenta il valore di verita falso.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 339
La programmazione nel linguaggio C Tipi user-defined
Esempio:typedef enum {false, true} boolean;
boolean even (int n){if (n % 2 == 0)
return true;else
return false;}
boolean implies (boolean p, boolean q){
if (p)return q;
elsereturn true;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 340
La programmazione nel linguaggio C Tipi user-defined
Esempio: Uso del costrutto switch con tipi enumerati
typedef enum {lun, mar, mer, gio, ven, sab, dom} Giorno;
Giorno g;
...
switch (g) {
case lun: case mar: case mer: case gio: case ven:
printf("Giorno lavorativo");
break;
case sab: case dom:
printf("Week-end");
break;
}
void stampaGiorno(Giorno g) {
switch (g) {
case lun: printf("lun");
break;
...
case dom: printf("dom");
break;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 341
La programmazione nel linguaggio C Tipi user-defined
Tipi strutturati user-definedI Il C non possiede tipi strutturati built-in, ma fornisce dei costruttori che
permettono di definire tipi strutturati anche piuttosto complessi.
I Array e puntatori possono essere visti come costruttori di tipo (definisconoun tipo di dato non semplice a partire da tipi esistenti).
Uso di typedef con array e puntatori
I In generale, una dichiarazione di tipo mediante typedef ha la forma di unadichiarazione di variabile preceduta dalla parola chiave typedef, e con ilnome di tipo al posto del nome della variabile.
I Nel caso di array e puntatori:typedef TipoElemento TipoArray[Dimensione];
typedef TipoPuntato *TipoPuntatore;
Esempio:typedef int ArrayDieciInteri[10];
typedef int MatriceTreXQuattro[3][4];
typedef int *PuntIntero;
ArrayDieciInteri vet; /* int vet[10]; */
PunIntero p; /* int *p; */
MatriceTreXQuattro mat, mat1; /* int mat[3][4]; int mat1[3][4]; */
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 342
La programmazione nel linguaggio C Tipi user-defined
Il costruttore structI Una struttura e un’aggregazione di elementi che possono essere
eterogenei (di tipo diverso).Esempio:struct persona {
char nome[15];char cognome[20];int eta;sesso s; }
I la parola chiave struct introduce la definizione della strutturaI persona e l’etichetta della struttura, attribuisce un nome alla
definizione della strutturaI nome, cognome, eta, s sono detti campi della struttura
I Naturalmente e possibile definire strutture con campi omogenei
struct data {int giorno;int mese;int anno; }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 343
La programmazione nel linguaggio C Tipi user-defined
Campi di una struttura
I devono avere nomi univoci all’interno di una struttura
I strutture diverse possono avere campi con lo stesso nome
I i nomi dei campi possono coincidere con altri nomi gia utilizzati (es.per variabili o funzioni)
Esempio:
int x;
struct a { char x; int y; };
struct b { int w; float x; };
I possono essere di tipo diverso (semplice o altre strutture)
I un campo di una struttura non puo essere del tipo struttura che si stadefinendo
I un campo puo pero essere di tipo puntatore alla struttura
Esempio:
struct s { int a;
struct s *p; };
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 344
La programmazione nel linguaggio C Tipi user-defined
Dichiarazione di variabili di tipo struttura
I La definizione di una struttura non provoca allocazione di memoria,ma introduce un nuovo tipo di dato.
Esempio: struct persona tizio, docenti[10], *p;I tizio e una variabile di tipo struct personaI docenti e un vettore di 10 elementi di tipo struct personaI p e un puntatore a una struct persona
I Una variabile di tipo struttura puo essere dichiarata contestualmentealla definizione della struttura.
Esempio:
struct studente { | struct {char nome[20]; | char nome[20];long matricola; | long matricola;struct data ddn; | struct data ddn;
} s1, s2; | } s1, s2;
I In questo caso si puo anche omettere l’etichetta di struttura.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 345
La programmazione nel linguaggio C Tipi user-defined
Uso di typedef con strutture
I Attraverso typedef e possibile associare un nome ad un tipo definitomediante il costruttore struct.
Esempio:
struct data { int giorno, mese, anno; };
typedef struct data Data;
I Data e un sinonimo di struct data, che puo essere utilizzato nelledichiarazioni di variabili.
Data d1, d2;Data appelli[10], *pd;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 346
La programmazione nel linguaggio C Tipi user-defined
Operazioni sulle strutture
I Si possono assegnare variabili di tipo struttura a variabili dello stessotipo struttura.
Esempio:Data d1, d2;...d1 = d2;
I Non e possibile invece effettuare il confronto tra due variabili di tipostruttura.
Esempio:struct data d1, d2;if (d1 == d2) ... Errore!
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 347
La programmazione nel linguaggio C Tipi user-defined
I L’equivalenza di tipo tra strutture e per nome.
Esempio:struct s1 { int i; };struct s2 { int i; };struct s1 a, b;struct s2 c;
a = b; OK a e b sono dello stesso tipo
a = c; Errore! a e c non sono dello stesso tipo
I Si puo ottenere l’indirizzo di una variabile di tipo struttura tramitel’operatore &.
I Si puo rilevare la dimensione di una struttura con sizeof.
Esempio: sizeof(struct data)
I Attenzione: non e detto che la dimensione di una struttura sia parialla somma delle dimensioni dei singoli campi.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 348
La programmazione nel linguaggio C Tipi user-defined
Accesso ai campi di una strutturaI I campi di una struttura si comportano come variabili del tipo corrispondente
I L’accesso avviene tramite l’operatore punto
Esempio:Data oggi;
oggi.giorno = 7; oggi.mese = 5; oggi.anno = 2008;
printf("%d %d %d", oggi.giorno, oggi.mese, oggi.anno);
I Accesso tramite un puntatore alla struttura.
Esempio:Data oggi, *pd;
pd = &oggi;
(*pd).giorno = 7; (*pd).mese = 5; (*pd).anno = 2008;
N.B. Ci vogliono le () perche “.” ha priorita piu alta di “*”.
I Operatore freccia: combina il dereferenziamento e l’accesso al campo dellastruttura.
Esempio:
pd->giorno = 7; pd->mese = 5; pd->anno = 2008;
I Nota: pd->giorno e semplicemente una abbreviazione per (*pd).giorno.prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 349
La programmazione nel linguaggio C Tipi user-defined
Esempio: Accesso al campo di una struttura che e a sua volta campo diun’altra struttura.
struct dipendente{ Persona datiDip;Data dataAssunzione;int stipendio;
};typedef struct dipendente Dipendente;
Dipendente dip, *p;...dip.dataAssunzione.giorno = 3;dip.dataAssunzione.mese = 4;dip.dataAssunzione.anno = 1997;...(p->dataAssunzione).giorno = 5;(p->stipendio) = (p->stipendio) + 120;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 350
La programmazione nel linguaggio C Tipi user-defined
Inizializzazione di strutture
I Puo avvenire, come per i vettori, con un elenco di inizialzzatori.
Esempio: Data oggi = { 7, 5, 2008 }I Se ci sono meno inizializzatori di campi della struttura, i campi
rimanenti vengono inizializzati a 0 (o al valore speciale NULL, se ilcampo e un puntatore).
Passaggio di parametri di tipo struttura
I E come per i parametri di tipo semplice:I il passaggio e per valore =⇒ viene fatta una copia dell’intera struttura
dal parametro attuale a quello formaleI e comunque possibile simulare il passaggio per indirizzo attraverso un
puntatore
Nota: per passare per valore ad una funzione un vettore (il vettore,non il puntatore al suo primo elemento) e sufficiente racchiuderlo inuna struttura.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 351
La programmazione nel linguaggio C Tipi user-defined
Esempio:
struct dipendente{ Persona datiDip;Data dataAssunzione;int stipendio;
};typedef struct dipendente Dipendente;
void aumento(Dipendente *p, int percentuale){
int incremento;incremento = (p -> stipendio) * percentuale / 100;p -> stipendio = p -> stipendio + incremento;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 352
La programmazione nel linguaggio C Liste collegate
Liste
I E molto comune dover rappresentare sequenze di elementi tutti dellostesso tipo e fare operazioni su di esse.
Esempi: sequenza di interi (23 46 5 28 3)sequenza di caratteri (’x’ ’r’ ’f’)sequenza di persone con nome e data di nascita
I Finora abbiamo usato gli array per realizzare tali strutture,nonostante cio porti talvolta a un impiego inefficiente della memoria.
I Vediamo adesso un modo basato sull’allocazione dinamica di variabili,che ci permette di realizzare liste di elementi in maniera che lamemoria fisica utilizzata corrisponda meglio a quella astratta, cioe’ alnumero di elementi della sequenza che vogliamo rappresentare.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 353
La programmazione nel linguaggio C Liste collegate
Diversi modi di rappresentare sequenze di elementi
1. Rappresentazione sequenziale: tramite arrayI Vantaggi:
I l’accesso agli elementi e diretto (tramite indice) ed efficienteI l’ordine degli elementi e quello in memoria =⇒ non servono strutture
dati addizionaliI e semplice manipolare l’intera struttura (copia, ordinamento, . . . )
I Svantaggi:I dobbiamo avere un’idea precisa della dimensione della sequenzaI inserire o eliminare elementi al centro e complicato ed inefficiente
(bisogna spostare gli elementi che vengono dopo)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 354
La programmazione nel linguaggio C Liste collegate
2. Rappresentazione collegata
I La sequenza di elementi viene rappresentata da una struttura di daticollegata, realizzata tramite strutture e puntatori.
I Ogni elemento e rappresentato con una struttura C:I un campo (o piu campi se necessario) per l’elemento (ad es. int)I un campo puntatore alla struttura che rappresenta l’elemento
successivo (ovviamente, tale struttura ha tipo indentico a quello dellastruttura corrente)
I L’ultimo elemento non ha un elemento successivoI il campo puntatore ha valore NULL che assume quindi il significato di
“fine lista”.
I L’inizio della lista e individuato da una variabile del tipo dei puntatoriai vari elementi.
I Sara nostra abitudine attribuire a questa variabile il nome stesso dellalista, identificando il concetto di “inizio lista” ( o “testa della lista”)con la lista stessa.
I l’accesso a una lista avviene attraverso il puntatore al primo elemento.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 355
La programmazione nel linguaggio C Liste collegate
Graficamente
25 8 5
lista
I La variabile lista, di tipo puntatore, e utilizzata per accedere allasequenza.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 356
La programmazione nel linguaggio C Liste collegate
Esempio: Sequenze di interi.
struct EL {int info;struct EL *next;
};typedef struct EL ElementoLista;typedef ElementoLista *ListaDiElementi;
1. La prima dichiarazione struct EL definisce un primo campo, info,di tipo int e permette di dichiarare il campo next come puntatore altipo strutturato che si sta definendo;
2. la seconda dichiarazione utilizza typedef per ridenominare il tipostruct EL come ElementoLista;
3. la terza dichiarazione definisce il tipo ListaDiElementi comepuntatore al tipo ElementoLista.
I A questo punto possiamo definire variabili di tipo lista:
ListaDiElementi Lista1, Lista2;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 357
La programmazione nel linguaggio C Liste collegate
Esempio: Creazione di una lista di tre interi fissati: (8, 3, 15)
ElementoLista El1,El2,El3;
ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista=&El1;
El1.info = 8;
El1.next = &El2;
El2.info = 3;
El2.next = &El3;
El3.info = 15;
El3.next = NULL;
lista El1
El2
El3
Nota: per poter usare la costante NULL dobbiamo importare il filestdlib.h
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 358
La programmazione nel linguaggio C Liste collegate
Esempio: Creazione di una lista di tre interi fissati: (8, 3, 15)
ElementoLista El1,El2,El3;
ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista=&El1;
El1.info = 8;
El1.next = &El2;
El2.info = 3;
El2.next = &El3;
El3.info = 15;
El3.next = NULL;
lista El1
El2
El3
Nota: per poter usare la costante NULL dobbiamo importare il filestdlib.h
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 359
La programmazione nel linguaggio C Liste collegate
Esempio: Creazione di una lista di tre interi fissati: (8, 3, 15)
ElementoLista El1,El2,El3;
ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista=&El1;
El1.info = 8;
El1.next = &El2;
El2.info = 3;
El2.next = &El3;
El3.info = 15;
El3.next = NULL;
lista El1
El2
El3
8
Nota: per poter usare la costante NULL dobbiamo importare il filestdlib.h
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 360
La programmazione nel linguaggio C Liste collegate
Esempio: Creazione di una lista di tre interi fissati: (8, 3, 15)
ElementoLista El1,El2,El3;
ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista=&El1;
El1.info = 8;
El1.next = &El2;
El2.info = 3;
El2.next = &El3;
El3.info = 15;
El3.next = NULL;
lista El1
El2
El3
8
3
Nota: per poter usare la costante NULL dobbiamo importare il filestdlib.h
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 361
La programmazione nel linguaggio C Liste collegate
Esempio: Creazione di una lista di tre interi fissati: (8, 3, 15)
ElementoLista El1,El2,El3;
ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista=&El1;
El1.info = 8;
El1.next = &El2;
El2.info = 3;
El2.next = &El3;
El3.info = 15;
El3.next = NULL;
lista El1
El2
El3
8
3
15
Nota: per poter usare la costante NULL dobbiamo importare il filestdlib.h
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 362
La programmazione nel linguaggio C Liste collegate
I Nel programma che abbiamo appena visto per creare una lista di treelementi dobbiamo dichiarare tre variabili di tipo ElementoLista.
I Il numero degli elementi della lista deve essere deciso a tempo dicompilazione.
I Non e possibile, per esempio, creare una lista con un numero dielementi letti in ingresso. Ma allora qual’e il vantaggio rispettoall’array?
I Quello che abbiamo visto non e l’unico modo. . . .
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 363
La programmazione nel linguaggio C Liste collegate
Allocazione Dinamica della memoria
I L’allocazione dinamica della memoria e possibile in C grazieall’utilizzo di alcune funzioni messe a disposizione dalla libreriastandard (standard library).
I Le due funzioni che usiamo sonoI malloc: consente di allocare dinamicamente memoria per una variabile
di un tipo specificatoI free: consente di rilasciare dinamicamente memoria (precedentemente
allocata con malloc)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 364
La programmazione nel linguaggio C Liste collegate
malloc
I La chiamata di funzione
malloc(sizeof(TipoDato));
crea in memoria una variabile di tipo TipoDato, e restituisce comerisultato l’indirizzo della variabile creata.
I Se p e una variabile di tipo puntatore a TipoDato, l’istruzione
p=malloc(sizeof(TipoDato));
assegna l’indirizzo restituito dalla funzione malloc a p.I Una variabile creata dinamicamente e necessariamente anonima: a
essa si puo fare riferimento solo tramite un puntatore
a differenza di una variabile dichiarata mediante un proprioidentificatore, che puo essere riferita sia direttamente sia tramite unpuntatore
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 365
La programmazione nel linguaggio C Liste collegate
free
I Se p e l’indirizzo di una variabile allocata dinamicamente, la chiamata
free(p);
rilascia lo spazio di memoria puntato da p
la corrispondente memoria fisica e resa disponibile per qualsiasi altrouso.
I free deve ricevere come parametro attuale un puntatore al quale erastato assegnato come valore l’indirizzo restituito da una funzione diallocazione dinamica di memoria (cioe malloc).
Heap
I Poiche le variabili dinamiche possono essere create e distrutte in unqualsiasi punto del programma esse non possono essere allocate sullostack.
I Vengono allocate in un’altra zona di memoria chiamata heap(mucchio). La loro gestione risulta molto piu inefficiente.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 366
La programmazione nel linguaggio C Liste collegate
Produzione di garbage (spazzatura)
I Si verifica quando la memoria allocata dinamicamente risultalogicamente inaccessibile, e quindi sprecata, perche non esiste alcunriferimento ad essa.Esempio:P=malloc(sizeof(TipoDato));...P=Q;
I In questo modo la cella puntata da P subito dopo l’assegnamento P=Qperde ogni possibilita di accesso (da cui il termine spazzatura).
P
Q
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 367
La programmazione nel linguaggio C Liste collegate
Produzione di garbage (spazzatura)
I Si verifica quando la memoria allocata dinamicamente risultalogicamente inaccessibile, e quindi sprecata, perche non esiste alcunriferimento ad essa.Esempio:P=malloc(sizeof(TipoDato));...P=Q;
I In questo modo la cella puntata da P subito dopo l’assegnamento P=Qperde ogni possibilita di accesso (da cui il termine spazzatura).
P
Q
garbage
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 368
La programmazione nel linguaggio C Liste collegate
Riferimenti fluttuanti (dangling references)I Simmetrico al problema precedente: consiste nel creare riferimenti
fasulli a zone di memoria logicamente inesistenti.Esempio:P=Q;free(Q);
I L’operazione free(Q) provoca il rilascio della memoria allocata perla variabile cui Q punta
I P punta a una zona di memoria non piu significativa (puo essereriusata in futuro).
I *P comporterebbe l’accesso all’indirizzo fisico puntato da P el’interpretazione del suo contenuto come un valore del tipo di *P conrisultati imprevedibili.
P
Q
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 369
La programmazione nel linguaggio C Liste collegate
Riferimenti fluttuanti (dangling references)I Simmetrico al problema precedente: consiste nel creare riferimenti
fasulli a zone di memoria logicamente inesistenti.Esempio:P=Q;free(Q);
I L’operazione free(Q) provoca il rilascio della memoria allocata perla variabile cui Q punta
I P punta a una zona di memoria non piu significativa (puo essereriusata in futuro).
I *P comporterebbe l’accesso all’indirizzo fisico puntato da P el’interpretazione del suo contenuto come un valore del tipo di *P conrisultati imprevedibili.
P
Q ?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 370
La programmazione nel linguaggio C Liste collegate
I Produzione di garbage e riferimenti fluttuanti hanno svantaggisimmetrici:
I la prima comporta spreco di memoriaI la seconda comporta risultati imprevedibili e scorretti.
I La seconda e piu pericolosa della prima e in alcuni linguaggi non eprevista l’istruzione free.
I Viene lasciato al supporto del linguaggio l’onere di effettuare garbagecollection (“raccolta rifiuti”).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 371
La programmazione nel linguaggio C Liste collegate
Esempio di allocazione dinamica#include <stdio.h>
#include <stdlib.h>
main()
{
int x = 10, *P1, *P2;
P1 = malloc(sizeof(int));
*P1 = 2*x;
P2 = P1;
*P2= 3*(*P1);
printf("x=%d *P1=%d *P2=%d \n", x, *P1, *P2);
free(P1);
}PILA HEAP
X
P1
P2 ?
?
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 372
La programmazione nel linguaggio C Liste collegate
Esempio di allocazione dinamica#include <stdio.h>
#include <stdlib.h>
main()
{
int x = 10, *P1, *P2;
P1 = malloc(sizeof(int));
*P1 = 2*x;
P2 = P1;
*P2= 3*(*P1);
printf("x=%d *P1=%d *P2=%d \n", x, *P1, *P2);
free(P1);
}PILA HEAP
X
P1
P2 ?
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 373
La programmazione nel linguaggio C Liste collegate
Esempio di allocazione dinamica#include <stdio.h>
#include <stdlib.h>
main()
{
int x = 10, *P1, *P2;
P1 = malloc(sizeof(int));
*P1 = 2*x;
P2 = P1;
*P2= 3*(*P1);
printf("x=%d *P1=%d *P2=%d \n", x, *P1, *P2);
free(P1);
}PILA HEAP
X
P1
P2 ?
10
20
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 374
La programmazione nel linguaggio C Liste collegate
Esempio di allocazione dinamica#include <stdio.h>
#include <stdlib.h>
main()
{
int x = 10, *P1, *P2;
P1 = malloc(sizeof(int));
*P1 = 2*x;
P2 = P1;
*P2= 3*(*P1);
printf("x=%d *P1=%d *P2=%d \n", x, *P1, *P2);
free(P1);
}PILA HEAP
X
P1
P2
10
20
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 375
La programmazione nel linguaggio C Liste collegate
Esempio di allocazione dinamica#include <stdio.h>
#include <stdlib.h>
main()
{
int x = 10, *P1, *P2;
P1 = malloc(sizeof(int));
*P1 = 2*x;
P2 = P1;
*P2= 3*(*P1);
printf("x=%d *P1=%d *P2=%d \n", x, *P1, *P2);
free(P1);
}PILA HEAP
X
P1
P2
10
60
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 376
La programmazione nel linguaggio C Liste collegate
Esempio di allocazione dinamica#include <stdio.h>
#include <stdlib.h>
main()
{
int x = 10, *P1, *P2;
P1 = malloc(sizeof(int));
*P1 = 2*x;
P2 = P1;
*P2= 3*(*P1);
printf("x=%d *P1=%d *P2=%d \n", x, *P1, *P2);
free(P1);
}PILA HEAP
X
P1
P2
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 377
La programmazione nel linguaggio C Liste collegate
Creazione di una lista di tre interi fissati: (8, 3, 15)ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista = malloc(sizeof(ElementoLista)); /* allocazione primo elemento */
lista->info = 8;
lista->next = malloc(sizeof(ElementoLista)); /* secondo elemento */
lista->next->info = 3;
lista->next->next = malloc(sizeof(ElementoLista)); /* terzo elemento */
lista->next->next->info = 15;
lista->next->next->next = NULL;
PILA HEAP
lista ?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 378
La programmazione nel linguaggio C Liste collegate
Creazione di una lista di tre interi fissati: (8, 3, 15)ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista = malloc(sizeof(ElementoLista)); /* allocazione primo elemento */
lista->info = 8;
lista->next = malloc(sizeof(ElementoLista)); /* secondo elemento */
lista->next->info = 3;
lista->next->next = malloc(sizeof(ElementoLista)); /* terzo elemento */
lista->next->next->info = 15;
lista->next->next->next = NULL;
PILA HEAP
lista info next
8
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 379
La programmazione nel linguaggio C Liste collegate
Creazione di una lista di tre interi fissati: (8, 3, 15)ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista = malloc(sizeof(ElementoLista)); /* allocazione primo elemento */
lista->info = 8;
lista->next = malloc(sizeof(ElementoLista)); /* secondo elemento */
lista->next->info = 3;
lista->next->next = malloc(sizeof(ElementoLista)); /* terzo elemento */
lista->next->next->info = 15;
lista->next->next->next = NULL;
PILA HEAP
lista info next
8
info next
3
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 380
La programmazione nel linguaggio C Liste collegate
Creazione di una lista di tre interi fissati: (8, 3, 15)ListaDiElementi lista; /* puntatore al primo elemento della lista */
lista = malloc(sizeof(ElementoLista)); /* allocazione primo elemento */
lista->info = 8;
lista->next = malloc(sizeof(ElementoLista)); /* secondo elemento */
lista->next->info = 3;
lista->next->next = malloc(sizeof(ElementoLista)); /* terzo elemento */
lista->next->next->info = 15;
lista->next->next->next = NULL;
PILA HEAP
lista info next
8
info next
3
info next
15
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 381
La programmazione nel linguaggio C Liste collegate
Osservazioni:
I lista e di tipo ListaDiElementi, quindi e un puntatore e non unastruttura
I la zona di memoria per ogni elemento della lista (non per ognivariabile di tipo ListaDiElementi) deve essere allocataesplicitamente con malloc
I Esiste un modo piu semplice di creare la lista di 3 elementi?
I Creiamo la lista a partire dal fondo!
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 382
La programmazione nel linguaggio C Liste collegate
ListaDiElementi aux, lista = NULL;
aux = malloc(sizeof(ElementoLista));
aux->info = 15; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista)
aux->info = 8; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista));
aux->info = 3; aux->next = lista;
lista = aux;
PILA HEAP
lista
aux ?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 383
La programmazione nel linguaggio C Liste collegate
ListaDiElementi aux, lista = NULL;
aux = malloc(sizeof(ElementoLista));
aux->info = 15; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista)
aux->info = 8; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista));
aux->info = 3; aux->next = lista;
lista = aux;
PILA HEAP
lista info next
15
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 384
La programmazione nel linguaggio C Liste collegate
ListaDiElementi aux, lista = NULL;
aux = malloc(sizeof(ElementoLista));
aux->info = 15; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista)
aux->info = 8; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista));
aux->info = 3; aux->next = lista;
lista = aux;
PILA HEAP
lista info next
15
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 385
La programmazione nel linguaggio C Liste collegate
ListaDiElementi aux, lista = NULL;
aux = malloc(sizeof(ElementoLista));
aux->info = 15; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista)
aux->info = 8; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista));
aux->info = 3; aux->next = lista;
lista = aux;
PILA HEAP
lista info next
15
aux
info next
8
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 386
La programmazione nel linguaggio C Liste collegate
ListaDiElementi aux, lista = NULL;
aux = malloc(sizeof(ElementoLista));
aux->info = 15; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista)
aux->info = 8; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista));
aux->info = 3; aux->next = lista;
lista = aux;
PILA HEAP
lista info next
15
aux
info next
8
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 387
La programmazione nel linguaggio C Liste collegate
ListaDiElementi aux, lista = NULL;
aux = malloc(sizeof(ElementoLista));
aux->info = 15; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista)
aux->info = 8; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista));
aux->info = 3; aux->next = lista;
lista = aux;
PILA HEAP
lista info next
15
aux
info next
8
info next
3
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 388
La programmazione nel linguaggio C Liste collegate
ListaDiElementi aux, lista = NULL;
aux = malloc(sizeof(ElementoLista));
aux->info = 15; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista)
aux->info = 8; aux->next = lista;
lista = aux;
aux = malloc(sizeof(ElementoLista));
aux->info = 3; aux->next = lista;
lista = aux;
PILA HEAP
lista info next
15
aux
info next
8
info next
3
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 389
La programmazione nel linguaggio C Liste collegate
Operazioni sulle liste
I Definiamo una serie di procedure e funzioni per operare sulle liste.
I Usiamo liste di interi per semplicita, ma tutte le operazioni sonorealizzabili in modo del tutto analogo su liste di altro tipo (salvo rareeccezioni)
I Facciamo riferimento alle dichiarazioni dei tipi ElementoLista eListaDiElementi viste in precedenza
Inizializzazione
I Definiamo una procedura che inizializza una lista assegnando il valoreNULL alla variabile testa della lista.
I Tale variabile deve essere modificata e quindi passata per indirizzo.
I Cio provoca, nell’intestazione della procedura, la presenza di unpuntatore a puntatore.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 390
La programmazione nel linguaggio C Liste collegate
void Inizializza(ListaDiElementi *lista)
{
*lista=NULL;
}
I Supponiamo ora che Inizializza sia chiamata passando comeparametro l’indirizzo della variabile Lista1 di tipoListaDiElementi, ad esempio:
ListaDiElementi Lista1;
Inizializza(&Lista1);
PILA
Lista1 ?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 391
La programmazione nel linguaggio C Liste collegate
void Inizializza(ListaDiElementi *lista)
{
*lista=NULL;
}
I Supponiamo ora che Inizializza sia chiamata passando comeparametro l’indirizzo della variabile Lista1 di tipoListaDiElementi, ad esempio:
ListaDiElementi Lista1;
Inizializza(&Lista1);
PILA
Lista1 ?
RDA Inizializza
lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 392
La programmazione nel linguaggio C Liste collegate
void Inizializza(ListaDiElementi *lista)
{
*lista=NULL;
}
I Supponiamo ora che Inizializza sia chiamata passando comeparametro l’indirizzo della variabile Lista1 di tipoListaDiElementi, ad esempio:
ListaDiElementi Lista1;
Inizializza(&Lista1);
PILA
Lista1
RDA Inizializza
lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 393
La programmazione nel linguaggio C Liste collegate
void Inizializza(ListaDiElementi *lista)
{
*lista=NULL;
}
I Supponiamo ora che Inizializza sia chiamata passando comeparametro l’indirizzo della variabile Lista1 di tipoListaDiElementi, ad esempio:
ListaDiElementi Lista1;
Inizializza(&Lista1);
PILA
Lista1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 394
La programmazione nel linguaggio C Liste collegate
Cosa succederebbe se passassimo il parametro per valore?void Inizializza(ListaDiElementi lista)
{
lista=NULL;
}
main() {
ListaDiElementi Lista1;
Inizializza(Lista1);
...
}
PILA
Lista1 ?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 395
La programmazione nel linguaggio C Liste collegate
Cosa succederebbe se passassimo il parametro per valore?void Inizializza(ListaDiElementi lista)
{
lista=NULL;
}
main() {
ListaDiElementi Lista1;
Inizializza(Lista1);
...
}
PILA
Lista1 ?
lista ?
RDA Inizializza
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 396
La programmazione nel linguaggio C Liste collegate
Cosa succederebbe se passassimo il parametro per valore?void Inizializza(ListaDiElementi lista)
{
lista=NULL;
}
main() {
ListaDiElementi Lista1;
Inizializza(Lista1);
...
}
PILA
Lista1 ?
lista
RDA Inizializza
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 397
La programmazione nel linguaggio C Liste collegate
Cosa succederebbe se passassimo il parametro per valore?void Inizializza(ListaDiElementi lista)
{
lista=NULL;
}
main() {
ListaDiElementi Lista1;
Inizializza(Lista1);
...
}
PILA
Lista1 ?
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 398
La programmazione nel linguaggio C Liste collegate
Stampa degli elementi di una lista
I Data la lista
vogliamo che venga stampato:
5 –> 8 –> 4 –> //
5 8 4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 399
La programmazione nel linguaggio C Liste collegate
Versione iterativa:
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
I N.B.: lis = lis->next fa puntare lis all’elemento successivo dellalista
I Attenzione: Possiamo usare lis per scorrere la lista perche, avendoutilizzato il passaggio per valore, le modifiche a lis non siripercuotono sul parametro attuale.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 400
La programmazione nel linguaggio C Liste collegate
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(Lista1);
...
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 401
La programmazione nel linguaggio C Liste collegate
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(Lista1);
...
}
PILA HEAP
5
8
4
Lista1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 402
La programmazione nel linguaggio C Liste collegate
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(Lista1);
...
}
PILA HEAP
5
8
4
Lista1
lis
RDA StampaLista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 403
La programmazione nel linguaggio C Liste collegate
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(Lista1);
...
}
PILA HEAP
5
8
4
Lista1
lis
RDA StampaLista
Output
5 -->
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 404
La programmazione nel linguaggio C Liste collegate
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(Lista1);
...
}
PILA HEAP
5
8
4
Lista1
lis
RDA StampaLista
Output
5 --> 8 -->
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 405
La programmazione nel linguaggio C Liste collegate
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(Lista1);
...
}
PILA HEAP
5
8
Lista1
lis
RDA StampaLista
Output
5 --> 8 --> 4 --> //
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 406
La programmazione nel linguaggio C Liste collegate
void StampaLista(ListaDiElementi lis)
{
while (lis != NULL)
{
printf("%d -->", lis->info);
lis = lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 --> 4 --> //
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 407
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 408
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
PILA HEAP
5
8
4
Lista1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 409
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
PILA HEAP
5
8
Lista1
lis
RDA StampaLista
Output
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 410
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
PILA HEAP
5
8
Lista1
lis
RDA StampaLista
Output
5 -->
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 411
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
PILA HEAP
5
8
Lista1
lis
RDA StampaLista
Output
5 --> 8 -->
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 412
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
PILA HEAP
5
8
Lista1
lis
RDA StampaLista
Output
5 --> 8 --> 4 -->
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 413
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
PILA HEAP
5
8
Lista1
lis
RDA StampaLista
Output
5 --> 8 --> 4 --> //
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 414
La programmazione nel linguaggio C Liste collegate
Cosa sarebbe successo passando il parametro per indirizzo?void StampaLista(ListaDiElementi *lis)
{
while (*lis != NULL)
{
printf("%d -->", *lis->info);
*lis = *lis->next;
}
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaLista(&Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 --> 4 --> //
4
garbage!!
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 415
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 416
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 417
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
4
lis
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 418
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 -->
-->
4
lis
lis
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 419
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 -->
-->
4
lis
lis
lis
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 420
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 --> 4 -->
-->
4
lis
lis
lis
lis
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 421
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 --> 4 --> //
-->
4
lis
lis
lis
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 422
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 --> 4 --> //
-->
4
lis
lis
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 423
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 --> 4 --> //
-->
4
lis
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 424
La programmazione nel linguaggio C Liste collegate
Versione ricorsivavoid StampaListaRic(ListaDiElementi lis)
{
if (lis != NULL)
{
printf("%d ", lis->info);
StampaListaRic(lis->next);
}
else
printf("//");
}
main()
{
ListaDiElementi Lista1;
...
/* costruzione lista 5 --> 8 --> 4 */
...
StampaListaRic(Lista1);
...
}
PILA HEAP
5
8
Lista1
Output
5 --> 8 --> 4 --> //
-->
4
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 425
La programmazione nel linguaggio C Liste collegate
Inserimento di un nuovo elemento in testa
1. allochiamo una nuova struttura per l’elemento (malloc)2. assegnamo il valore da inserire al campo info della struttura3. concateniamo la nuova struttura con la vecchia lista4. il puntatore iniziale della lista viene fatto puntare alla nuova struttura
=⇒ la lista da modificare deve essere passata per indirizzo
PILA HEAP
5
8
4
lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 426
La programmazione nel linguaggio C Liste collegate
Inserimento di un nuovo elemento in testa
1. allochiamo una nuova struttura per l’elemento (malloc)2. assegnamo il valore da inserire al campo info della struttura3. concateniamo la nuova struttura con la vecchia lista4. il puntatore iniziale della lista viene fatto puntare alla nuova struttura
=⇒ la lista da modificare deve essere passata per indirizzo
PILA HEAP
5
8
aux
4
lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 427
La programmazione nel linguaggio C Liste collegate
Inserimento di un nuovo elemento in testa
1. allochiamo una nuova struttura per l’elemento (malloc)2. assegnamo il valore da inserire al campo info della struttura3. concateniamo la nuova struttura con la vecchia lista4. il puntatore iniziale della lista viene fatto puntare alla nuova struttura
=⇒ la lista da modificare deve essere passata per indirizzo
PILA HEAP
8
aux
4
lista
5
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 428
La programmazione nel linguaggio C Liste collegate
Inserimento di un nuovo elemento in testa
1. allochiamo una nuova struttura per l’elemento (malloc)2. assegnamo il valore da inserire al campo info della struttura3. concateniamo la nuova struttura con la vecchia lista4. il puntatore iniziale della lista viene fatto puntare alla nuova struttura
=⇒ la lista da modificare deve essere passata per indirizzo
PILA HEAP
8
aux
4
lista
5
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 429
La programmazione nel linguaggio C Liste collegate
Inserimento di un nuovo elemento in testa
1. allochiamo una nuova struttura per l’elemento (malloc)2. assegnamo il valore da inserire al campo info della struttura3. concateniamo la nuova struttura con la vecchia lista4. il puntatore iniziale della lista viene fatto puntare alla nuova struttura
=⇒ la lista da modificare deve essere passata per indirizzo
PILA HEAP
8
aux
4
lista
5
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 430
La programmazione nel linguaggio C Liste collegate
void InserisciTestaLista(ListaDiElementi *lista, int elem)
{
ListaDiElementi aux;
aux = malloc(sizeof(ElementoLista));
aux->info = elem;
aux->next = *lista;
*lista = aux;
}
I il primo parametro e la lista da modificare (passata per indirizzo)I il secondo parametro e l’elemento da inserire (passato per indirizzo)
I Attenzione: nel caso di liste di tipo TipoElemLista la procedura puoessere generalizzata se su tale tipo e definito l’assegnamento
EsercizioImpostare una chiamata alla procedura e tracciare l’evoluzione di pilae heap
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 431
La programmazione nel linguaggio C Liste collegate
void InserisciTestaLista(ListaDiElementi *lista, TipoElemLista elem)
{
ListaDiElementi aux;
aux = malloc(sizeof(ElementoLista));
aux->info = elem;
aux->next = *lista;
*lista = aux;
}
I il primo parametro e la lista da modificare (passata per indirizzo)I il secondo parametro e l’elemento da inserire (passato per indirizzo)
I Attenzione: nel caso di liste di tipo TipoElemLista la procedura puoessere generalizzata se su tale tipo e definito l’assegnamento
EsercizioImpostare una chiamata alla procedura e tracciare l’evoluzione di pilae heap
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 432
La programmazione nel linguaggio C Liste collegate
Cancellazione del primo elemento
I se la lista e vuota non facciamo nulla
I altrimenti eliminiamo il primo elemento
=⇒ la lista deve essere passata per indirizzo
I cancellare significa anche deallocare la memoria occupata dall’elemento
=⇒ dobbiamo invocare free passando il puntatore all’elemento dacancellare=⇒ e necessario un puntatore ausiliario
PILA HEAP
8
4
lista
5
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 433
La programmazione nel linguaggio C Liste collegate
Cancellazione del primo elemento
I se la lista e vuota non facciamo nulla
I altrimenti eliminiamo il primo elemento
=⇒ la lista deve essere passata per indirizzo
I cancellare significa anche deallocare la memoria occupata dall’elemento
=⇒ dobbiamo invocare free passando il puntatore all’elemento dacancellare=⇒ e necessario un puntatore ausiliario
PILA HEAP
8
4
lista
5
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 434
La programmazione nel linguaggio C Liste collegate
Cancellazione del primo elemento
I se la lista e vuota non facciamo nulla
I altrimenti eliminiamo il primo elemento
=⇒ la lista deve essere passata per indirizzo
I cancellare significa anche deallocare la memoria occupata dall’elemento
=⇒ dobbiamo invocare free passando il puntatore all’elemento dacancellare=⇒ e necessario un puntatore ausiliario
PILA HEAP
8
4
lista
5
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 435
La programmazione nel linguaggio C Liste collegate
Cancellazione del primo elemento
I se la lista e vuota non facciamo nulla
I altrimenti eliminiamo il primo elemento
=⇒ la lista deve essere passata per indirizzo
I cancellare significa anche deallocare la memoria occupata dall’elemento
=⇒ dobbiamo invocare free passando il puntatore all’elemento dacancellare=⇒ e necessario un puntatore ausiliario
PILA HEAP
8
aux
4
lista
5
10
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 436
La programmazione nel linguaggio C Liste collegate
Cancellazione del primo elemento
I se la lista e vuota non facciamo nulla
I altrimenti eliminiamo il primo elemento
=⇒ la lista deve essere passata per indirizzo
I cancellare significa anche deallocare la memoria occupata dall’elemento
=⇒ dobbiamo invocare free passando il puntatore all’elemento dacancellare=⇒ e necessario un puntatore ausiliario
PILA HEAP
8
aux
4
lista
5
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 437
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista){ListaDiElementi aux;if (*lista != NULL)
{aux = *lista;*lista = (*lista)->next;free(aux);
}}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 438
La programmazione nel linguaggio C Liste collegate
Cancellazione di tutta una lista
void CancellaLista(ListaDiElementi *lista)
{
ListaDiElementi aux;
while (*lista != NULL) {
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
I Osserviamo che il corpo del ciclo corrisponde alle azioni dellaprocedura CancellaPrimo. Possiamo allora scrivere:
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
I Si noti il parametro attuale della chiamata a CancellaPrimo, che elista (di tipo ListaDiElementi *) e non &lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 439
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 440
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista
5
main
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 441
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista
5
main
lista
Can
c
Lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 442
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista
5
main
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 443
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista
5
main
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 444
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista
5
main
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 445
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista m
ain
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 446
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista m
ain
lista
Can
c
Lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 447
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista m
ain
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 448
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
8
4
lista m
ain
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 449
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
4
lista m
ain
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 450
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
4
lista m
ain
lista
Can
c
Lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 451
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
4
lista m
ain
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 452
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
4
lista m
ain
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 453
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
lista m
ain
lista
Can
c
Lista
lista
Can
c
Prim
o
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 454
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
lista m
ain
lista
Can
c
Lista
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 455
La programmazione nel linguaggio C Liste collegate
void CancellaPrimo(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
}
}
void CancellaLista(ListaDiElementi *lista)
{
while (*lista != NULL)
CancellaPrimo(lista);
}
main()
{
ListaDiElementi lista;
...
CancellaLista(&lista);
...
}
PILA HEAP
lista m
ain
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 456
La programmazione nel linguaggio C Liste collegate
Visione ricorsiva delle liste
I Una lista di elementi e una struttura dati ricorsiva per sua natura1. data una lista L di elementi x1, . . . , xn
2. dato un ulteriore elemento x0
3. anche la concatenazione di x0 e L e una listaI Si noti che in 1. L puo anche essere la lista vuota
x0 x1 xn
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 457
La programmazione nel linguaggio C Liste collegate
Visione ricorsiva delle liste
I Una lista di elementi e una struttura dati ricorsiva per sua natura1. data una lista L di elementi x1, . . . , xn
2. dato un ulteriore elemento x0
3. anche la concatenazione di x0 e L e una listaI Si noti che in 1. L puo anche essere la lista vuota
x0 x1 xn
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 458
La programmazione nel linguaggio C Liste collegate
Cancellazione lista: versione ricorsivaI Sfruttiamo la visione ricorsiva della struttura dati lista per realizzare
la cancellazione in modo ricorsivo1. la cancellazione della lista vuota non richiede alcuna azione2. la cancellazione della lista ottenuta come concatenazione dell’elemento
x e della lista L richiede l’eliminazione di x e la cancellazione di L
I la traduzione in C e immediata
void CancellaListaRic(ListaDiElementi *lista){
ListaDiElementi aux;if (*lista != NULL){aux = *lista;*lista = (*lista)->next;free(aux);CancellaListaRic(lista);
}}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 459
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
5
main
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 460
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
5
main
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 461
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
5
main
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 462
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
5
main
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 463
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
main
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 464
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 465
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 466
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
8
4
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 467
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
4
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 468
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
4
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
lista C
anc
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 469
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
4
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
lista C
anc
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 470
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
4
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
lista C
anc
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 471
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
lista C
anc
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 472
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
lista C
anc
Ric
aux
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 473
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
lista C
anc
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 474
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
lista
main
lista
Can
c
Ric
aux
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 475
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
lista
main
lista
Can
c
Ric
aux
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 476
La programmazione nel linguaggio C Liste collegate
void CancellaListaRic(ListaDiElementi *lista)
{
ListaDiElementi aux;
if (*lista != NULL)
{
aux = *lista;
*lista = (*lista)->next;
free(aux);
CancellaListaRic(lista);
}
}
PILA HEAP
lista
main
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 477
La programmazione nel linguaggio C Liste collegate
Appartenenza di un elemento ad una lista
p = lista; /* puntatore al primo elemento */
trovato = false;
while (!trovato && p != NULL)
{
if (p->info == el) /* elemento corrente */
trovato = true;
else
p = p->next;
}
I Ricordiamo la ricerca lineare incerta su vettori
I sostituiamo l’indice i con un puntatore p
I scorriamo la lista attraverso p
I l’elemento corrente e quello puntato da p
I Incapsuliamo questo codice in una funzione a valori booleani
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 478
La programmazione nel linguaggio C Liste collegate
Appartenenza di un elemento ad una lista
boolean Appartiene(TipoElementoLista elem, ListaDiElementi lista)
{
boolean trovato = false;
while (lista != NULL && !trovato)
if (lista->info==elem)
trovato = true;
else
lista = lista->next;
return trovato;
}
I Non c’e bisogno di un puntatore ausiliario per scorrere la lista
=⇒ il passaggio per valore consente di scorrere utilizzando ilparametro formale!
I Abbiamo assunto che sul tipo TipoElementoLista sia definitol’operatore di uguaglianza ==
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 479
La programmazione nel linguaggio C Liste collegate
Versione ricorsiva
boolean Appartiene(TipoElementoLista elem, ListaDiElementi lis)
{
if (lis == NULL)
return false;
else if (lis->info==elem)
return true;
else
return (Appartiene(elem, lis->next));
}
I Un elemento elemI non appartiene alla lista vuotaI appartiene alla lista con testa x se elem coincide con xI appartiene alla lista con testa x diversa da elem e resto L se e solo se
appartiene a L
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 480
La programmazione nel linguaggio C Liste collegate
Inserimento di un elemento in codaI Se la lista e vuota coincide con l’inserimento in testa
=⇒ e necessario il passaggio per indirizzo!I Se la lista non e vuota, bisogna scandirla fino in fondo
=⇒ dobbiamo usare un puntatore ausiliario per la scansioneI La scansione deve terminare in corrispondenza dell’ultimo elemento al
quale va collegato quello nuovo
*lista
8 3 15
ultimo
aux
15
5
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 481
La programmazione nel linguaggio C Liste collegate
Inserimento di un elemento in codaI Se la lista e vuota coincide con l’inserimento in testa
=⇒ e necessario il passaggio per indirizzo!I Se la lista non e vuota, bisogna scandirla fino in fondo
=⇒ dobbiamo usare un puntatore ausiliario per la scansioneI La scansione deve terminare in corrispondenza dell’ultimo elemento al
quale va collegato quello nuovo
*lista
8 3 15
aux
15
5
ultimo
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 482
La programmazione nel linguaggio C Liste collegate
Inserimento di un elemento in codaI Se la lista e vuota coincide con l’inserimento in testa
=⇒ e necessario il passaggio per indirizzo!I Se la lista non e vuota, bisogna scandirla fino in fondo
=⇒ dobbiamo usare un puntatore ausiliario per la scansioneI La scansione deve terminare in corrispondenza dell’ultimo elemento al
quale va collegato quello nuovo
*lista
8 3 15
aux
15
5
ultimo
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 483
La programmazione nel linguaggio C Liste collegate
Inserimento di un elemento in codaI Se la lista e vuota coincide con l’inserimento in testa
=⇒ e necessario il passaggio per indirizzo!I Se la lista non e vuota, bisogna scandirla fino in fondo
=⇒ dobbiamo usare un puntatore ausiliario per la scansioneI La scansione deve terminare in corrispondenza dell’ultimo elemento al
quale va collegato quello nuovo
*lista
8 3 15
aux
15
5
ultimo
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 484
La programmazione nel linguaggio C Liste collegate
Codice della versione iterativa
void InserzioneInCoda(ListaDiElementi *lista, TipoElementoLista elem)
{
ListaDiElementi ultimo; /* puntatore usato per la scansione */
ListaDiElementi aux;
/* creazione del nuovo elemento */
aux = malloc(sizeof(ElementoLista));
aux->info = elem;
aux->next = NULL;
if (*lista == NULL)
*lista = aux;
else {
ultimo = *lista;
while (ultimo->next != NULL)
ultimo = ultimo->next;
/* concatenazione del nuovo elemento in coda alla lista */
ultimo->next = aux;
}
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 485
La programmazione nel linguaggio C Liste collegate
Inserimento ricorsivo di un elemento in coda
I Caratterizzazione induttiva dell’inserimento in coda
Sia nuovaLista la lista ottenuta inserendo elem in coda a lista.
1. se lista e vuota, allora nuovaLista e costituita dal solo elem(caso base)
2. altrimenti nuovaLista e ottenuta da lista facendo l’inserimento di elemin coda al resto di lista (caso ricorsivo)
void InserzioneInCoda(ListaDiElementi *lista, TipoElementoLista elem)
{
if (*lista == NULL)
{
*lista = malloc(sizeof(ElementoLista));
(*lista)->info = elem;
(*lista)->next = NULL;
}
else
InserzioneInCoda(&((*lista)->next), elem);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 486
La programmazione nel linguaggio C Liste collegate
Cancellazione della prima occorrenza di un elemento
I si scandisce la lista alla ricerca dell’elemento
I se l’elemento non compare non si fa nullaI altrimenti, a seconda di dove si trova l’elemento, si distinguono tre
casi
1. l’elemento e il primo della lista: si aggiorna il puntatore iniziale inmodo che punti all’elemento successivo=⇒ passaggio per indirizzo!!
2. l’elemento non e ne il primo ne l’ultimo: si aggiorna il campo nextdell’elemento che precede quello da cancellare in modo che puntiall’elemento che segue
3. l’elemento e l’ultimo: come (2), solo che il campo next dell’elementoprecedente viene posto a NULL
I in tutti e tre i casi bisogna liberare la memoria occupata dall’elementoda cancellare
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 487
La programmazione nel linguaggio C Liste collegate
Osservazioni:I per poter aggiornare il campo next dell’elemento precedente, bisogna
fermare la scansione sull’elemento precedente (e non su quello dacancellare)
I per fermare la scansione dopo aver trovato e cancellato l’elemento, siutilizza una sentinella booleana
8 3 15
precedente
15
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 488
La programmazione nel linguaggio C Liste collegate
void CancellaElementoLista(ListaDiElementi *lista, TipoElementoLista elem)
{
ListaDiElementi prec; /* puntatore all’elemento precedente */
ListaDiElementi corr; /* puntatore all’elemento corrente */
boolean trovato; /* usato per terminare la scansione */
if (*lista != NULL)
if ((*lista)->info==elem)
{ /* cancella il primo elemento */
CancellaPrimo(lista);
}
else /* scansione della lista e cancellazione dell’elemento */
prec = *lista; corr = prec->next; trovato = false;
while (corr != NULL && !trovato)
if (corr->info == elem)
{ /* cancella l’elemento */
trovato = true; /* provoca l’uscita dal ciclo */
prec->next = corr->next;
free(corr); }
else {
prec = prec->next; /* avanzamento dei due puntatori */
corr = corr->next; }
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 489
La programmazione nel linguaggio C Liste collegate
Versione ricorsiva:
void CancellaElementoLista(ListaDiElementi *lista, TipoElementoLista elem)
{
if (*lista != NULL)
if ((*lista)->info== elem)
{ /* cancella il primo elemento */
CancellaPrimo(lista);
}
else /* cancella elem dal resto */
CancellaElementoLista(&((*lista)->next), elem);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 490
La programmazione nel linguaggio C Liste collegate
Cancellazione di tutte le occorrenze di un elemento
Versione iterativa
I analoga alla cancellazione della prima occorrenza
I pero, dopo aver trovato e cancellato l’elemento, bisogna continuare lascansione
I ci si ferma solo quando si e arrivati alla fine della lista
=⇒ non serve la sentinella booleana per fermare la scansione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 491
La programmazione nel linguaggio C Liste collegate
Cancellazione di tutte le occorrenze di un elemento
Caratterizzazione induttiva
Sia ris la lista ottenuta cancellando tutte le occorrenze di elem da lista.Allora:
1. se lista e la lista vuota, allora ris e la lista vuota (caso base)
2. altrimenti, se il primo elemento di lista e uguale ad elem, allora ris eottenuta da lista cancellando il primo elemento e tutte le occorrenzedi elem dal resto di lista (caso ricorsivo)
3. altrimenti ris e ottenuta da lista cancellando tutte le occorrenze dielem dal resto di lista (caso ricorsivo)
EsercizioImplementare le due versioni
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 492
La programmazione nel linguaggio C Liste collegate
Versione iterativavoid CancellaTuttiLista(ListaDiElementi *lista, TipoElementoLista elem)
{
ListaDiElementi prec; /* puntatore all’elemento precedente */
ListaDiElementi corr; /* puntatore all’elemento corrente */
boolean trovato = false;
while ((*lista != NULL) && !trovato) /* cancella le occorrenze */
if ((*lista)->info!=elem) /* di elem in testa */
trovato = true;
else CancellaPrimo(lista);
if (*lista != NULL)
{
prec = *lista; corr = prec->next;
while (corr != NULL)
if (corr->info == elem)
{ /* cancella l’elemento */
prec->next = corr->next;
free(corr);
corr = prec->next;}
else {
prec = prec->next; /* avanzamento dei due puntatori */
corr = corr->next; }
}
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 493
La programmazione nel linguaggio C Liste collegate
Versione ricorsiva
void CancellaTuttiLista(ListaDiElementi *lista, TipoElementoLista elem)
{
ListaDiElementi aux;
if (*lista != NULL)
if ((*lista)->info==elem)
{ /* cancellazione del primo elemento */
CancellaPrimo(lista);
/* cancellazione di elem dal resto della lista */
CancellaTuttiLista(lista, elem);
}
else
CancellaTuttiLista(&((*lista)->next), elem);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 494
La programmazione nel linguaggio C Liste collegate
Inserimento di un elemento in una lista ordinata
I Data una lista (ad es. di interi) gia ordinata (in ordine crescente), sivuole inserire un nuovo elemento mantenendo l’ordinamento.
Versione iterativa: per esercizio
Versione ricorsiva
I Caratterizziamo il problema induttivamenteI Sia ris la lista ottenuta inserendo l’elemento elem nella lista ordinata
lista.
1. se lista e la lista vuota, allora ris e costituita solo da elem (caso base)2. se il primo elemento di lista e maggiore o uguale a elem, allora ris e
ottenuta da lista inserendo elem in testa (caso base)3. altrimenti ris e ottenuta da lista inserendo ordinatamente elem nel
resto di lista (caso ricorsivo)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 – pag. 495
INFORMATICA 1ESERCITAZIONI
Corso di Laurea in Fisicaa.a. 2007/08
prof. Paolo Mancarella
1Dipartimento di Informaticaemail: [email protected]
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 1
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Lo stato
I Insieme di associazioni tra nomi e valori.x 5
I Nelle specifiche, si vogliono spesso indicare valori costanti magenerici. Utilizziamo le seguenti convenzioni:
I usiamo lettere minuscole per i nomi simbolici utilizzati nellostato e negli algoritmi;
I usiamo lettere maiuscole per indicare costanti generiche
I Laddove necessario, possiamo specificare condizioni alcontorno sul dominio di appartenenza di tali costanti.
Esempio:{naturale A, base 2} con A ≥ 0
Al nome simbolico naturale e associato un generico valorenaturale (A ≥ 0), mentre al nome simbolico base e associatala costante 2.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 2
Pseudo-linguaggio: Algoritmi Semplici algoritmi
ATTENZIONE: all’interno degli algoritmi non e possibile utilizzareesplicitamente le costanti generiche.
Esempio: Elevamento a potenzaSpecifica:Stato iniziale: { base A, esponente B } con A>0 e B≥0Stato finale: { risultato AB}
Algoritmo:risultato = 1;while (esponente > 0) {
risultato = risultato * A; NO!esponente = esponente - 1;
}
Le espressioni non possono contenere costanti generiche (proprioperche tali!).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 3
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Esempi
Esempio: Ordinare tre valori interi distinti tra loroStato iniziale:
{x A, y B, z C
}con A,B,C distinti tra loro
Stato finale:{
x max({A,B,C}),y max({A,B,C} \ {max({A,B,C})}),z min({A,B,C})
}Algoritmo
Passo 1. “Ordiniamo” x e y, portandoci nello stato intermedioStato 1:
{x max(A,B), y min(A,B), z C
}Passo 2. “Ordiniamo” x e z, portandoci nello stato intermedio
Stato 2:
{x max({A,B,C}), y min(A,B),z min(max(A,B), C)
}Passo 3. “Ordiniamo” y e z, portandoci nello stato finale desiderato
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 4
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Soluzione nello pseudo-linguaggioif (x < y)
{temp = x;
x = y;
y = temp;
}else ;{
x max(A,B), y min(A,B), z C}
if (x < z)
{temp = x;
x = z;
z = temp;
}else ;{
x max({A,B,C}), y min(A,B), z min(max(A,B), C)}
if (y < z)
{temp = y;
y = z;
z = temp;
}else ;
Stato finale
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 5
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Esempio: Calcolo del fattoriale di un numero naturale.Ricordiamo che:
n! =
{1 se n = 0
1 · 2 · . . . · (n − 1) · n se n > 0
Specifica:Stato iniziale:
{n N
}con N ≥ 0
Stato finale:{n N, fatt N!
}I Attenzione: la specifica impone che il valore di n non deve
cambiare!
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 6
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Soluzione:
fatt = 1;i = 1;while (i <= n){
fatt = fatt * i;i = i + 1;
}I i viene spesso chiamata variabile di controllo del ciclo, dal momento
che l’esecuzione di ogni iterazione dipende dal valore di i.
Viene incrementata di 1 alla fine di ogni iterazione
=⇒ per ogni valore di i ∈ [1,N] . . . . . .
I Ad ogni iterazione del ciclo, vale la seguente proprieta:
fatt =i−1∏j=1
j = (i-1)! (•)
I Al termine del ciclo, quando cioe i=N+1, la (•) diventa
fatt = N!, ovvero lo stato finale desiderato.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 7
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Sequenze: nomi simbolici con indiceConsentiamo anche l’uso di nomi simbolici con indice, perrappresentare sequenze.
c[i] 5dove i e un valore naturale. Ad esempio:
{i K, c[0] 0, . . . , c[K − 1] 0} K ≥ 0Nello stato sono presenti:I un’associazione per il nome simbolico i, al quale e associato
un valore naturale K.I K associazioni per i nomi simbolici c[0], c[1], . . . , c[K-1], a
ciascuno dei quali e associato il valore 0.
All’interno degli algoritmi, consentiamo di riferire nomi simbolicicon indice nella forma c[exp] dove exp deve essere una espressionea valori naturali.Anche in questo caso exp non deve contenere costanti generiche(nell’esempio, non e lecito un assegnamento del tipo c[K-1] = 5,mentre e lecito c[i-1] = 5).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 8
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Esempio: Calcolare il numero di elementi pari in una sequenza data.Stato iniziale: {dim K, c[1] V1, . . . , c[K] VK} con K > 0Stato finale: {count #{ j | j ∈ [1,K] ∧ Vj pari} }I Dobbiamo calcolare ∑
1≤ j≤ dimc[j] pari
1
I Di nuovo, utilizziamo un ciclo controllato da una variabile dicontrollo i che assume tutti i valori nell’intervallo [1,dim].
I Facciamo in modo che, ad ogni iterazione, valga la seguenteproprieta
count =∑
1≤ j≤ i-1c[j] pari
1
I Se, alla fine del ciclo, i=dim+1, abbiamo quanto desiderato e cioe
count =∑
1≤ j≤ dimc[j] pari
1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 9
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Soluzione:count = 0;
i = 1; punto 1
while (i <= dim)
{if (c[i] % 2 == 0)
count = count + 1;
else ;
i = i + 1;
}
I Nello stato iniziale del while, al punto (1), count 0, i 1 edunque ∑
1≤ j≤ i-1cj pari
1 =∑
1≤ j≤ 0cj pari
1 = 0 = count
I il corpo del while mantiene vera la proprieta
count =∑
1≤ j≤ i-1cj pari
1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 10
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Considerazioni generali
I In molti problemi e necessario operare allo stesso modo sututti gli elementi di un intervallo dato
per ogni j ∈ [a,b] OPj
esempio:b∑
j=aexpj
I in tutti questi casi si ricorre a cicli in cui una variabile dicontrollo permette di scandire tutto l’intervallo di interessei = a;while (i <= b){
〈operazione in funzione di i〉i = i+1;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 11
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Esercizi proposti
Problema 1: Calcolare il numero di occorrenze di un valore dato in unasequenza dataStato iniziale: {dim K, val V, c[1] V1, . . . , c[K] VK} con K > 0Stato finale: {occ #{ j | j ∈ [1,K] ∧ Vj = V} }
Problema 2: Calcolare il massimo e il minimo di una sequenza data diinteriStato iniziale: {dim K, c[1] V1, . . . , c[K] VK} con K > 0Stato finale: {massimo max({V1,. . . ,VK}),
minimo min({V1,. . . ,VK})}
Problema 3: Calcolare il numero di occorrenze del valore massimo inuna sequenza di interiStato iniziale: ? Stato finale: ?
Problema 4: Calcolare il numero di occorrenze di una cifra nellarappresentazione decimale di un numero naturale
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 12
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Esercizi proposti
Problema 1: Calcolare il numero di occorrenze di un valore dato in unasequenza dataStato iniziale: {dim K, val V, c[1] V1, . . . , c[K] VK} con K > 0Stato finale: {occ #{ j | j ∈ [1,K] ∧ Vj = V} }
Problema 2: Calcolare il massimo e il minimo di una sequenza data diinteriStato iniziale: {dim K, c[1] V1, . . . , c[K] VK} con K > 0Stato finale: {massimo max({V1,. . . ,VK}),
minimo min({V1,. . . ,VK})}
Problema 3: Calcolare il numero di occorrenze del valore massimo inuna sequenza di interiStato iniziale: ? Stato finale: ?
Problema 4: Calcolare il numero di occorrenze di una cifra nellarappresentazione decimale di un numero naturale
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 12
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Soluzione problema 1:Stato iniziale: {dim K, val V, c1 V1, . . . , cK VK} con K > 0Stato finale: {occ #{ j | j ∈ [1,K] ∧ Vj = V} }
occ = 0;i = 1;while (i <= dim){
if (c[i] == val)occ = occ + 1;
else ;i = i + 1;
}
Ad ogni iterazione del ciclo vale la proprieta:occ = #{ j | j ∈ [1,i) ∧ c[j] = val}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 13
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Soluzione problema 2Stato iniziale: {dim K, c1 V1, . . . , cK VK} con K > 0Stato finale: {massimo max({V1,. . . ,VK}),
minimo min({V1,. . . ,VK})}
I Preoccupiamoci prima di calcolare il massimo
I Scorriamo l’intera sequenza, attraverso una variabile di controllo i,facendo in modo che, ad ogni scansione, valga la proprieta
massimo = max{c[j] | j ∈ [1, i)
}massimo = c[1];i = 2;while (i <= dim){ qui massimo = max
{c[1], ..., c[i-1]
}if (c[i] > massimo)
massimo = c[i];else ;i = i + 1; anche qui massimo = max
{c[1], ..., c[i-1]
}}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 14
Pseudo-linguaggio: Algoritmi Semplici algoritmi
I Il calcolo del minimo e analogo. Otteniamo:
massimo = c[1];minimo = c[1];i = 2;while (i <= dim){
if (c[i] > massimo) calcolo del massimomassimo = c[i];
else ;if (c[i] < minimo) calcolo del minimo
minimo = c[i];else ;i = i + 1;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 15
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Soluzione problema 3Stato iniziale:
{dim K, c[1] V1, . . . , cK VK
}Stato finale:
{occ #{j | j ∈ [1,K] ∧ cj = max{c1, . . . , cK}}
}I Un algoritmo ingenuo:
I Calcoliamo il valore massimo come nel problema 2I Scandiamo nuovamente la sequenza per contare il numero di
occorrenze del massimo
I Comporta una duplice scansione della sequenza
I Un algoritmo che comporta una singola scansione si ottieneadattando quello visto per il calcolo del massimo
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 16
Pseudo-linguaggio: Algoritmi Semplici algoritmi
massimo = c1;i = 2;occ = 1;while (i < dim){
if (c[i] > massimo){
massimo = c[i];occ = 1;
}else
if (c[i] == massimo)occ = occ + 1;
else ;i = i + 1;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 17
Pseudo-linguaggio: Algoritmi Semplici algoritmi
Soluzione problema 4Stato iniziale: {numero N, cif C} con N > 0Stato finale:
{occ #{ j | j ∈ [0,K] ∧ Cj = C}
}dove N = (CK. . . C0)10
I Analogo al problema 1, ma questa volta dobbiamo anchecalcolare gli elementi della sequenza
I La lunghezza della sequenza non e nota a priori
n = numero; occ = 0;while (n != 0){
nuova cifra = n % 10;if (nuova cifra == cif)
occ = occ + 1;else ;n = n / 10;
}I questa volta la variabile di controllo e n
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 18
Pseudo-linguaggio: Algoritmi Semplici algoritmi
I Variante: acquisire un numero naturale ed una cifra decimale,contare il numero di occorrenze di quest’ultima nellarappresentazione decimale del numero letto, e produrlo inuscita.Input(numero);Input(cif);n = numero; occ = 0;while (n != 0){...if (nuova cifra == cif) ...}Output(occ);
I da uno stato iniziale che non contiene associazioni, o megliosu cui non facciamo alcuna ipotesi, ci portiamo in uno statoche corrisponde allo stato iniziale del problema precedente
I nello stato finale, produciamo in uscita il risultato calcolato
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 19
Il linguaggio C Tipi e costrutti di base
I Date le seguenti dichiarazioni
int intero;
char carattere;
float reale;
double realeLungo;
indicare il tipo delle seguenti espressioni:
1. carattere + reale2. reale + intero + realeLungo3. (int) reale + reale + (int) realeLungo4. (int) reale + (double) intero
I Scrivere un programma che legga un voto e assegni ad una variabile
di tipo carattere il giudizio corrispondente secondo la seguente
tabella:voto v giudizio18 > v g=’i’27 < v ≤ 30 g=’o’18 ≤ v ≤ 20 g=’s’23 < v ≤ 27 g=’d’20 < v ≤ 23 g=’b’
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 20
Il linguaggio C Tipi e costrutti di base
I Riscrivere il seguente frammento senza utilizzare il comandoswitch:switch (x % a){
case 1:case 2: y=y+1;
break;case 3: y=y-1;
break;default: y=2*y;
}I Scrivere un programma che legge due valori interi x e y e
stampa il valore della funzione f(x,y) definita come segue:
f(x,y) =
|x-y| se x 6= yx+12 se x=y ∧ dispari(x)
x2 se x=y ∧ pari(x)
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 21
Il linguaggio C Tipi e costrutti di base
I Date le seguenti dichiarazioni:int x;char c;float f;indicare quali dei seguenti assegnamenti richiedonoconversione implicita di tipo e quali no:1. c = x; 2. x = (int) c + f;3. f = (float)(x+c) 4. f = (float) x+ (float) c
I Scrivere un programma che legge una sequenza di naturalinon nulli terminata da 0 e calcola:
I la somma degli elementi pari nella sequenzaI il numero degli elementi dispari nella sequenzaI la posizione dell’ultimo elemento pari nella sequenza
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 22
Il linguaggio C Esercizi su array
I Scrivere un programma che:I legge una sequenza di 50 caratteriI rimpiazza nella sequenza tutti i caratteri non alfanumerici con
il carattere spazioI stampa la sequenza modificata
I Scrivere un programma che legge una sequenza di K caratteriche rappresentano un numero x in modulo e segno in base Bsu K-1 cifre (con K e B costanti naturali) e stampa il valore dix (si supponga che il primo carattere della sequenza sia o ilcarattere + o il carattere –, a rappresentare il segno delnumero).
I Scrivere un programma che legge una sequenza di K caratteriche rappresentano un numero x in complemento a 5 (con Kcostante naturale) e determina la rappresentazione di -x incomplemento a 5 su K cifre, supponendo che talerappresentazione esista.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 23
Il linguaggio C Esercizi su array
I Completare il seguente frammento di codice#define DIM ...
main()
{int pos, i, vet[DIM];
for (i=0; i<DIM; i++)
scanf("%d", &vet[i]);
/* CODICE DA COMPLETARE */
}in modo che la variabile pos contenga, al terminedell’esecuzione, la posizione dell’ultimo elemento non nullodella sequenza.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 24
INFORMATICA - CdL in FISICA –Esercitazione del 14/03/2008
ESERCIZIO 1• Sia x = −(75)10
(i) Rappresentare x, se possibile, in complemento a 6 con 3 cifre.
(ii) Rappresentare x e −x in complemento a 5 su 3 cifre.
ESERCIZIO 2Riscrivere il seguente frammento di codice utilizzando solo i seguenti costruttidi controllo: assegnamento, sequenza, blocco, while e if-else.
...for(x=0; x>w; x=x-1)
for(y=1; y<=t; y++){ scanf("%d", &a);j=j+a;
}...
ESERCIZIO 3Scrivere un programma che legge un valore intero x stampa il valore dellafunzione f(x) definita come segue:
f(x) =
x2 + 1 se 0 <= x <= 10 ∧ divide(x, 5)x + 1 se x > 10x+12 altrimenti
ESERCIZIO 4Scrivere un programma che legge una sequenza di caratteri che termina con \ne stampa:
• la lunghezza complessiva della sequenza (escluso il \n finale)
• il numero di cifre, il numero di lettere e il numero di caratteri non alfanu-merici che occorrono nella sequenza
• la posizione nella sequenza della prima cifra (-1 se non ci sono cifre);
• la posizione nella sequenza della prima lettera (-1 se non ci sono lettere);
• la posizione nella sequenza dell’ultimo carattere non alfanumerico (-1 senon ce ne sono).
Se ad esempio la sequenza digitata dall’utente e la seguente;Ab8c dE4%44;6Tr.g-T\n
un possibile output del programma e:
Lunghezza seq. : 20Num. cifre: 5Num. lettere: 9Num. non alfanumerici: 6Posizione prima cifra: 4Posizione prima lettera: 2Posizione ultimo non alfanumerico: 19
ESERCIZIO 5Completare il seguente programma C in modo che, al termine della sua ese-cuzione, gli elementi del vettore vet siano distribuiti nel vettore medesimo comesegue:
• tutte i valori pari si trovano nella porzione iniziale del vettore;
• tutti i valori dispari si trovano nella porzione finale del vettore.
#define DIM ...
main(){int vet[DIM];int i;/* AGGIUNGERE QUI EVENTUALI ALTRE DICHIARAZIONI DI VARIABILE */for (i=0; i<DIM; i++)
scanf("%d", &vet[i]);/* CODICE DA COMPLETARE */}
Se, ad esempio, dopo il ciclo di lettura il vettore vet e il seguente
2 15 3 8 5 10 -3 21 4
una possibile soluzione consiste nel redistribuire i valori di vet come segue:
2 8 10 4 15 3 5 -3 21
Nota bene: non e consentito utilizzare altre variabili strutturate oltre allavariabile vet.
Esercitazione
Uso di funzioni e librerie di funzioni
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008
1 – Uso di funzioni e librerie di funzioni Funzioni – 1.1
Funzioni
Il meccanismo delle funzioni/procedure consente di modularizzare un programma.
Esempio: Programma che stampa una tabella di potenze.
#include <stdio.h>
#define N 8
long potenza (int base, int esponente);
/* calcola baseˆesponente */
void intestazione();
/* stampa una intestazione */
void stampaTabellaPotenze(int m);
/* stampa la tabella di potenze iˆj con i,j in [1,n]*/
/* utilizza la funzione potenza */
main() {
intestazione();
stampaTabellaPotenze(N);
}
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 1
1 – Uso di funzioni e librerie di funzioni Funzioni – 1.1
Dopo la funzione main mettiamo le definizioni delle funzioni i cui prototipi sono stati dichiarati nella parte
dichiarativa.
long potenza (int base, int esponente)
/* calcola baseˆesponente */
{
int i;
long pot = 1;
for(i=1; i<=esponente; i++)
pot *= base;
return pot;
}
void intestazione()
{
printf("\n\n::::::::: TABELLA DI POTENZE :::::::::\n\n");
}
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 2
1 – Uso di funzioni e librerie di funzioni Funzioni – 1.1
void stampaTabellaPotenze(int m)
{
int i,j;
for (i=1; i<= m; i++)
{
for(j=1; j<=m; j++)
printf("%-10ld", potenza(i,j));
putchar(’\n’);
}
}
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 3
1 – Uso di funzioni e librerie di funzioni Funzioni – 1.1
Struttura tipica di un programma
• parte direttiva
#include <stdio.h>
#define N 8
• parte dichiarativa che comprende:
– dichiarazioni (prototipi) di funzioni/procedure
long potenza (int base, int esponente);
void intestazione();
void stampaTabellaPotenze(int m);
– altro ...
• il programma principale (main)
• le definizioni di funzioni/procedure
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 4
1 – Uso di funzioni e librerie di funzioni Compilazione separata – 1.2
Compilazione separata
Le definizioni delle funzioni utilizzate da un programma possono risiedere su files separati da quello che
contiene il programma principale.
int f3 (...) ; File principale
prog.c
definizione di f1 File separato
fun.cdefinizione di f2
definizione di f3
main () {<usa f1, f2, f3 > }
int f1 (...) ;int f2 (...) ;
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 5
1 – Uso di funzioni e librerie di funzioni Compilazione separata – 1.2
• Anche i files contenenti le definizioni delle funzioni devono avere estensione .c
• Possono essere compilati separatamente con l’opzione -c
> gcc -c fun.c
::: produce il file fun.o :::
Per ciascun file cosı compilato viene prodotto un corrispondente file con estensione .o che deve
essere utilizzato al momento della compilazione del file contenente il programma principale
> gcc prog.c fun.o
::: produce il file eseguibile a.out :::
• E comunque possibile compilare tutto assieme elencando tutti i file .c necessari
> gcc prog.c fun.c
::: produce il file eseguibile a.out :::
> gcc -o PROG prog.c fun.c
::: produce il file eseguibile PROG :::
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 6
1 – Uso di funzioni e librerie di funzioni Compilazione separata – 1.2
• Si possono utilizzare implementazioni diverse delle medesime funzioni.
Esempio: I files fun.c e funbis.c contengono definizioni diverse delle stesse funzioni.
> gcc -o PROG prog.c fun.o
in PROG vengono usate le definizioni di fun.c
> gcc -o PROGBIS prog.c funbis.o
in PROGBIS vengono usate le definizioni
di funbis.c
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 7
1 – Uso di funzioni e librerie di funzioni Compilazione separata – 1.2
• Se si modifica solo il programma principale non e necessario ricompilare le funzioni.
> gcc -c fun.c
:::: compilazione separata delle funzioni in fun.c ::::
> gcc -o PROG prog.c fun.o
:::: eseguibile in PROG ::::
> emacs prog.c
:::: modifiche a prog.c ::::
> gcc -o PROG1 prog.c fun.o
il nuovo eseguibile e’ in PROG1
• Se si modificano le funzioni si devono ricompilare entrambi.
> emacs fun.c
:::: modifiche a fun.c ::::
> gcc -c fun.c
:::: compilazione separata delle nuove funzioni ::::
> gcc -o PROG1 prog.c fun.o
:::: eseguibile in PROG1 ::::
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 8
1 – Uso di funzioni e librerie di funzioni Compilazione separata – 1.2
• Le dichiarazioni di funzioni possono essere collezionate in un file con estensione .h che l’utente puo
includere nella parte iniziale del programma esattamente come include le librerie standard.
Esempio:
long f1 (int , int) ;
#define N 8
File
mydefs.h
#include <stdio.h>#include "mydefs.h"
main() { ... }
void p (int) ;int f2 (char, int) ;
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 9
1 – Uso di funzioni e librerie di funzioni Compilazione separata – 1.2
• La compilazione avviene come nei casi precedenti: al momento della compilazione del file contenente
la funzioine main vanno elencati i files (.o se precedentemente compilati, .c se non ancora
compilati) contententi le definzioni delle funzioni i cui prototipi sono specificati nel file .h.
• In pratica e possibile definire una volta per tutte un insieme di librerie utente (tipicamente prototipi di
funzioni, definizioni di costanti, etc.). I files con estensione .h vengono di solito detti header files.
• La direttiva #include "mylib.h" importa le definizioni contenute nel file mylib.h.
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 10
1 – Uso di funzioni e librerie di funzioni Compilazione separata – 1.2
Esempio:
Eseguire i seguenti comandi
> cp ˜mancarel/compsep.tgz ./
> tar xzf compsep.tgz
> cd compsep0
> ls
• Il file vetIO.h contiene le dichiarazioni di funzioni di utlita per l’input/output di vettori di interi di
LUNG elementi, oltre alla definizione della costante LUNG.
• Il file vetIO.c contiene il codice delle funzioni dichiarate in vetIO.h
• Analizzare il codice main.c e definire in un file separato funzioni.c le funzioni i cui prototipi
sono dichiarati in main.
• Compilare ed eseguire il programma.
Prof. Paolo Mancarella Informatica I — Corso di Laurea in Fisica — A.A. 2007/2008 11
Il linguaggio C Ricerca e Verifica
Schemi di programma: ricerca e verifica
I Molti problemi riguardano la ricerca di elementi in intervalli ola verifica di proprieta.
I Sviluppiamo schemi di programma (dimostrabilmente corretti)che realizzano la ricerca e la verifica.
I La soluzione di problemi concreti consiste poi nellasostituzione di alcuni parametri degli schemi con valorispecifici dei problemi in esame.
I Distinguiamo due tipi di ricerca: ricerca certa e ricerca incerta.
I ricerca certa: si vuole determinare il minimo elemento di unintervallo [a,b) per il quale vale una certa proprieta P, sapendoche almeno un elemento dell’intervallo soddisfa P.
I ricerca incerta: si vuole determinare, se esiste, il minimoelemento di un intervallo [a,b) per il quale vale una certaproprieta P.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 25
Il linguaggio C Ricerca e Verifica
Ricerca certa
I Intervallo di ricerca: [a,b)
I Proprieta: P(·)I Ipotesi di certezza: ∃ i ∈ [a,b) . P(i)
I Stato finale:x = min { i∈ [a,b) | P(i)}.
I Lo schema generale per risolvere il problema e il seguente:
int x;x=a;while (!P(x))x=x+1;
I Nota: l’estremo destro dell’intervallo non serve.
I Si assume che la proprieta P sia esprimibile nel linguaggio.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 26
Il linguaggio C Ricerca e Verifica
Ricerca certa: esempio 1
I Calcolare la radice intera di un numero naturale.
I Si puo esprimere come problema di ricerca certa:b√Nc= min
{x∈ [0,N+1) | x2 ≤ N < (x+1)2
}I Dunque l’estremo sinistro dell’intervallo di ricerca, a nello
schema, in questo caso e 0, mentre l’estremo destro, b nelloschema, e N.
I Infine la proprieta P(x) dello schema e N < (x+1)2
int x;x=0;while ((x+1)*(x+1) <= N)
x=x+1;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 27
Il linguaggio C Ricerca e Verifica
Ricerca certa: esempio 2
I Determinare la posizione della prima occorrenza di un datoelemento in un array, sapendo che tale elemento vi occorrrealmeno una volta.
I Indichiamo con vet l’array e con DIM la sua dimensione
I Vogliamo determinare:x = min
{i∈ [0,DIM) | vet[i] = el
}I Possiamo istanziare lo schema come segue:
int x;x=0;while (vet[x]!=el)x=x+1;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 28
Il linguaggio C Ricerca e Verifica
Ricerca IncertaI Si vuole determinare, se esiste, il minimo elemento di un
intervallo [a,b) per il quale vale una certa proprieta P.I Perche lo schema di ricerca certa non va bene?
x=a;
while (!P(x))
x=x+1;
I Se l’elemento non c’e si vanno ad esaminare valori di x chesono al di fuori dell’intervallo di ricerca e per i quali la laproprieta P potrebbe addirittura non essere definita (errore atempo di esecuzione).
Esempio: Nel caso della ricerca incerta di un elemento in unarray di dimensione DIM si andrebbero ad esaminare elementidel tipo vet[x] con x >= DIM.
I Abbiamo bisogno di modificare lo schema in modo chel’analisi degli elementi avvenga solo all’interno dell’intervallodi ricerca e che la ricerca venga interrotta una volta esauritol’intervallo (e non individuato alcun elemento).
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 29
Il linguaggio C Ricerca e Verifica
Ricerca incerta
I Intervallo di ricerca: [a,b)
I Proprieta: P(·)I Stato finale: x = min
{i∈ [a,b) | P(i)
}min b
=⇒ dobbiamo stabilire quale valore calcolare se nessunelemento dell’intervallo soddisfa P: una buona scelta e ilvalore b, che sicuramente non fa parte dell’intervallo.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 30
Il linguaggio C Ricerca e Verifica
Ricerca incertaI Utilizziamo una variabile booleana trovato che fa da
sentinella
=⇒ impone l’uscita dal ciclo non appena si individua unelemento che soddisfa la proprieta
I in congiunzione con la sentinella, la guardia del ciclo assicurache l’intervallo di ricerca non sia esauritoint trovato = FALSE; /* inizialmente false */int x=a;while (!trovato && x<b)
if (P(x))trovato = TRUE; /*x soddisfa P */
elsex=x+1;
I Si suppone che le costanti TRUE e FALSE siano state definiteopportunamente, ad esempio mediante le direttive#define FALSE 0
#define TRUE 1
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 31
Il linguaggio C Ricerca e Verifica
All’uscita dal ciclo abbiamo due possibilita:
1. trovato ∧ x ∈ [a,b) ∧ x = min{i∈ [a,b) | P(i)
}I x e l’indice cercatoI il valore di verita di trovato e TRUE
2. ¬ trovato ∧ x=b ∧∀ i∈ [a,b). ¬ P(i)I nessun elemento nell’intervallo di ricerca soddisfa PI il valore di x e b (fuori dell’intervallo)I il valore di verita di trovato e FALSE
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 32
Il linguaggio C Ricerca e Verifica
Ricerca incerta: esempio
I Determinare la prima occorrenza di un elemento in un array.
I E un problema di ricerca incerta:min
{x∈ [0,DIM) | vet[x] = el
}min DIM
int trovato = FALSE;int x=0;while (!trovato && x<DIM)
if (vet[x]==el)trovato = TRUE;
elsex=x+1;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 33
Il linguaggio C Ricerca e Verifica
I Vi sono situazioni in cui la proprieta P della ricerca (certa oincerta) non e direttamente esprimibile nel linguaggio.
Esempio: Determinare (se c’e) la posizione del primoelemento di un array di interi che e uguale alla somma deglielementi che lo precedono.
I Si tratta di un problema di ricerca incerta in cui
1. l’intervallo [a,b] e [0,DIM]2. la proprieta P(x) e
vet[x]=x−1∑j=0
vet[j]
int trovato = FALSE;int x=0;while (!trovato && x<DIM)
if (vet[x]==x−1∑j=0
vet[j])
trovato = TRUE;else
x=x+1;
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 34
Il linguaggio C Ricerca e Verifica
I In questi casi si utilizza la seguente tecnica:
1. si rimpiazzano le espressioni critiche con variabili2. si impone l’uguaglianza tra le variabili cosi’ introdotte e le
corrispondenti espressioni “critiche”, aggiungendo quantonecessario al corpo del ciclo per mantenere vere taliuguaglianze
I Nell’esempio:
int trovato = FALSE;int x=0;int sommaPrecedenti = 0;while (!trovato && x<DIM)
if (vet[x]==sommaPrecedenti)trovato = TRUE;
else{ sommaPrecedenti = sommaPrecedenti + vet[x];
x=x+1; }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 35
Il linguaggio C Ricerca e Verifica
Verifica di una proprietaI Vogliamo verificare che tutti gli elementi di un intervallo
soddisfano una certa proprieta P.
1. Facciamo una ricerca incerta del minimo elementodell’intervallo per il quale non vale la proprieta P
2. Se non troviamo tale minimo, la verifica ha esito positivo,altrimenti ha esito negativo.
I Lo schema generale per risolvere questo problema.int trovato = FALSE;int x=a;while (!trovato && x<b)
if (!P(x))trovato = TRUE;
elsex=x+1;
if (trovato)/* esito negativo */
else/* esito positivo */
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 36
Il linguaggio C Ricerca e Verifica
Esempio: Sono dispari tutti gli elementi di un array? Cerchiamoil primo elemento pari!
int allOdd(int vet[], int dim){int trovato=FALSE;int i=0;while (!trovato && i<dim)
if (vet[i] % 2 == 0)trovato=TRUE;
elsei=i+1;
return (!trovato);}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 37
Il linguaggio C Ambienti e stack RDA
Esercizio 1: Indicare i valori stampati dal seguente programma mostrando l’evoluzionedella pila dei RDA
#include <stdio.h>
main() {
int x=10, y=20;
{
int z=5, x=5;
{
int z=10;
y=y+z;
x=x+z;
}
x=x+z;
y=y+x;
{
int y=30;
x=x+y;
z=z+x;
y=y+z;
}
x=x+y;
}
printf("%d %d\n", x,y);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 38
Il linguaggio C Ambienti e stack RDA
Esercizio 2: Indicare i valori stampati dal seguente programma mostrando l’evoluzionedella pila dei RDA
#include <stdio.h>
main()
{ int a = 1, b = 2, c = 3;
{ int a = 5;
b= b + 1;
c = a + b +c;
}
{ int b = 6;
a = a + b + c;
{ int c;
c = 2*a+b;
a = c + b;
}
printf("a = %d\n b = %d\n c = %d\n", a,b,c);
}
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 39
Il linguaggio C Ambienti e stack RDA
Esercizio 3: Indicare i valori stampati dal seguente programma mostrando l’evoluzionedella pila dei RDA
#include <stdio.h>
main()
{
int v = 3, w = 1, s = 0;
{
int w = 5;
s = foo(w,v);
v = w + s;
}
s= s + v + w;
printf("v = %d\n w = %d\n s = %d\n", v,w,s);
}
int foo(int v,int w)
{ int s = 1;
s = v + 2w +s;
return s; }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 40
Il linguaggio C Ambienti e stack RDA
Esercizio 4: Indicare, con precisione e rispettando l’ordine delle chiamate di printf,l’output prodotto dal seguente programma:
#include <stdio.h>
int foo (int *, int);
main()
{ int x = 10, y = 3;
int *p = &x;
{
int x = 100;
printf("PRIMA CHIAMATA \n");
x = foo(p, y);
}
printf("SECONDA CHIAMATA \n");
y = foo(p,1);
printf("x = %d y = %d\n", x, y); }
int foo (int *p, int y)
{ int r;
if (y>0)
{ r = foo(p, y-2);
*p = *p + y; }
else
r = *p + y;
printf("*p=%d y=%d r=%d\n", *p, y, r);
return r; }
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 41
Il linguaggio C Esercizi vari
Esercizio 1: Dire sotto quali condizioni il seguente programma C esicuramente corretto a tempo di esecuzione e, in tali casi, quale e ilvalore prodotto in output in funzione delle costanti A e B.
#include <stdio.h>
main()
{
int x = A;
int a[B];
int i;
int ris=0;
for (i=0; i<B; i++)
a[i]=i+1;
for(i=0; i<A; i++)
ris=ris+2*a[i];
printf("Risultato: %d\n", ris);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 42
Il linguaggio C Esercizi vari
Esercizio 2: Completare il seguente frammento di codice, rimpiazzando isimboli ? con opportune espressioni
#include <stdio.h>
main()
{
int x = ?;
int **p, *q, **r;
r = ?;
q = ?;
p = r;
**p = *q + **r;
printf("%d", **p);
}
in modo che il codice sia corretto sia a tempo di compilazione che atempo di esecuzione e che l’output prodotto sia 100.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 43
Il linguaggio C Esercizi vari
Esercizio 3: Dire sotto quali condizioni il seguente programma C ecorretto a tempo di esecuzione e, in tali casi, quante volte viene eseguitoil corpo del ciclo.
#include <stdio.h>
void leggiVet(int *, int);
main()
{
int a[100];
int i;
leggiVet(a, 100);
i=1;
while ((a[i-1] < a[i]) && (a[i] < a[i+1]))
i = i+1;
}
void leggiVet(int *vet, int lung)
{
int i;
for(i=0; i<lung; i++)
scanf("%d", vet+i);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 44
Il linguaggio C Esercizi vari
Esercizio 4: Scrivere il corpo di una procedura ricorsiva con prototipovoid foo()
che legge da standard input una sequenza di interi che termina con 0 ene stampa (in ordine inverso a quello di input) gli elementi strettamentepositivi.Ad esempio se la sequenza in input e
12 -3 6 8 -1 4 25 -2 0
la sequenza prodotta in output deve essere
25 4 8 6 12
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 45
Il linguaggio C Esercizi vari
Esercizio 5: Data la seguente definizione di tipotypedef enum false, true boolean;
scrivere il corpo della funzione ricorsiva check-ric con prototipoboolean check-ric(int *vet, int from, int to)
che restituisce true se la porzione di vettore vet compresa tra from e to
risulta ordinata in modo crescente, restituisce false altrimenti.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 46
Il linguaggio C Esercizi vari
Esercizio 6: Senza utilizzare costrutti iterativi ne variabili globali,scrivere una procedura che legge una sequenza di interi terminata da 0 estampa gli elementi non nulli della sequenza che sono immediatamentepreceduti da un elemento minore. Data ad esempio la sequenza in input
12 -3 6 8 -1 4 25 -2 0
quella prodotta in output deve essere
6 8 4 25
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 47
Il linguaggio C Algoritmi di ordinamento
Problema:
Data una sequenza di elementi in ordine qualsiasi, ordinarla.
I Questo e un problema fondamentale, che si presenta inmoltissimi contesti, ed in diverse forme.
I Nel nostro caso formuliamo il problema in termini diordinamento di vettori:
Dato un vettore A di n elementi, ordinarlo in modo crescente
I Per semplicita faremo sempre riferimento a vettori di interi.
5 2 4 6 1 3=⇒
1 2 3 4 5 6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 48
Il linguaggio C Algoritmi di ordinamento
Ordinamento per inserzione (insertion sort)I Esempio: Ordinamento di una mano di ramino
I si inizia con la mano sinistra vuota e le carte coperte sul tavoloI si prende dalla tavola una carta alla volta e la si inserisce nella
corretta posizione nella mano sinistraI · · ·I si termina quando si sono finite tutte le carte sul tavolo.
I Stesso procedimento per ordinare un vettore:I inizialmente il vettore rappresenta il mazzo sul tavoloI si usa un ciclo per analizzare uno alla volta gli elementi del
vettoreI Alla generica iterazione la situazione e la seguente
mano sinistra carte ancora da scoprire↑ nuova carta
I per inserire la nuova carta al posto giusto nella mano sinistradobbiamo
I scorrere gli elementi che lo precedono per decidere la posizioneche gli compete
I spostare di un posto verso destra gli elementi maggiori perfargli spazio.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 49
Il linguaggio C Algoritmi di ordinamento
EsempioIn verde le carte ancora da esaminare, in rosso quelle gia esaminate(mano sinistra). La nuova carta da esaminare e sottolineata.
5 2 4 6 1 35 2 4 6 1 32 5 4 6 1 32 4 5 6 1 32 4 5 6 1 31 2 4 5 6 31 2 3 4 5 6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 50
Il linguaggio C Algoritmi di ordinamento
I Una volta individuata la posizione k in cui inserire la nuovacarta dobbiamo farle spazio, ovvero spostare verso destra diuna posizione tutte le carte rosse da k in poi.
Esempio:1 2 4 5 6 31 2 4 5 6 31 2 4 5 61 2 4 5 61 2 4 5 6
I A questo punto possiamo piazzare la carta in modo ordinato
1 2 3 4 5 6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 51
Il linguaggio C Algoritmi di ordinamento
I Definiamo allora una procedura che sposta tutti gli elementi diun vettore verso destra di una posizione tra due indici datifrom e to
void shiftR(int v[], int from, int to){int i;for (i=to-1; i>=from; i--)
v[i+1] = v[i];}
I L’elemento in posizione to viene perso
I Bisogna procedere da destra verso sinistra (perche?)
I se to e minore o uguale a from non succede nulla
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 52
Il linguaggio C Algoritmi di ordinamento
Possiamo allora definire la procedura di di orfinamento perinserzione come segue
void sort(int v[], int dim){int h, curr, j=1;while (j<dim){ h=0;curr=v[j];
/* curr e’ l’elemento da piazzare */
while((v[h]<curr) && (h<j))h++;
/* curr va inserito in posizione h */
shiftR(v,h,j);v[h]=curr;j++;
}}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 53
Il linguaggio C Algoritmi di ordinamento
Ordinamento per selezione del minimo (selection sort)
I Esempio: Ordinamento di un mazzo di carteI si seleziona la carta piu piccola e si mette da parteI delle rimanenti si seleziona la piu piccola e si mette da parteI · · ·I si termina quando rimane una sola carta
I Ordinamento di un vettore:I per selezionare l’elemento piu piccolo tra quelli rimanenti si
utilizza un cicloI mettere da parte significa scambiare con l’elemento che si
trova nella posizione che compete a quello selezionato
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 54
Il linguaggio C Algoritmi di ordinamento
I in verde la parte che rimane da analizzarein blu l’elemento minimo selezionatoin marrone lo scambio effettuatoin rosso la parte ordinata
5 2 4 6 1 35 2 4 6 1 31 2 4 6 5 3
1 2 4 6 5 31 2 4 6 5 31 2 4 6 5 3
1 2 4 6 5 31 2 4 6 5 31 2 3 6 5 4
1 2 3 6 5 41 2 3 6 5 41 2 3 4 5 6
1 2 3 4 5 61 2 3 4 5 61 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 55
Il linguaggio C Algoritmi di ordinamento
Implementazione
int minPos(int v[], int from, int to);
/* calcola la posizione del minimo elemento di
v nella porzione [from,to] */
void swap(int *p, int *q);
/* scambia le variabili puntate da p e q */
/** PROCEDURA DI ORDINAMENTO PER SELEZIONE **/
void sort(int v[], int dim)
{
int i, min;
for(i=0; i<dim-1; i++)
{
min = minPos(v, i, dim-1);
swap(v+i, v+min);
}
}
Scrivere per esercizio le procedure swap e minpos
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 56
Il linguaggio C Algoritmi di ordinamento
int minPos(int v[], int from, int to) {
/* calcola la posizione del minimo elemento di
v nella porzione [from,to] */
int i, pos;
pos = from;
for (i=from+1; i<=to; i++)
if (v[i] < v[pos])
pos = i;
return pos;
}
void swap(int *p, int *q) {
/* scambia le variabili puntate da p e q */
int temp = *p;
*p = *q;
*q = temp;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 57
Il linguaggio C Algoritmi di ordinamento
Ordinamento a bolle (bubble sort)
I Si fanno salire gli elementi piu piccoli (“piu leggeri”) versol’inizio del vettore (“verso l’alto”), scambiandoli con quelliadiacenti.
I L’ordinamento e suddiviso in n-1 fasi:I fase 0: 0o elemento (il piu piccolo) in posizione 0I fase 1: 1o elemento in posizione 1I · · ·I fase n-2: (n-2)o elemento in posizione n-2, e quindi
(n-1)o elemento in posizione n-1
I Nella fase i: cominciamo a confrontare dal basso e portiamol’elemento piu piccolo (piu leggero) in posizione i
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 58
Il linguaggio C Algoritmi di ordinamento
5 2 4 6 1 35 2 4 6 1 35 2 4 1 6 35 2 1 4 6 35 1 2 4 6 31 5 2 4 6 3
1 5 2 4 6 31 5 2 4 3 61 5 2 3 4 61 5 2 3 4 61 2 5 3 4 6
1 2 5 3 4 6
1 2 3 5 4 6
1 2 3 4 5 6
1 2 3 4 5 6
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 59
Il linguaggio C Algoritmi di ordinamento
/** PROCEDURA BUBBLE SORT **/
void sort(int v[], int dim)
{
int temp,i,j;
for (i = 0; i < dim-1; i++) /* fase i-esima */
for (j = dim-1; j > i; j--) /* bolla piu’ leggera in posizione i */
if (v[j] < v[j-1])
swap(v+j, v+j-1);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 60
Il linguaggio C Algoritmi di ordinamento
Ordinamenti ricorsiviSelection Sort ricorsivo
I Il metodo del selection sort puo essere facilmente realizzato in modoricorsivo
I si definisce una procedura che ordina (ricorsivamente) la porzione diarray individuata da due indici from e to
I il minimo elemento della porzione viene messo in posizione from perpoi ordinare ricorsivamente la porzione tra from+1 e to
I Il caso base corrisponde all’ordinamento di una porzione fatta da unsolo elemento (e gia ordinata)
void SelectionSort(int v[], int from, int to){
if (from < to) {
int min = minPos(v,from,to);
swap(v+from, v+min);
SelectionSort(v, from+1, to);
} }
void sort(int v[], int dim) {
SelectionSort(v,0,dim-1);
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 61
Il linguaggio C Algoritmi di ordinamento
Merge sortSi divide il vettore da ordinare in due parti:
I si ordina ricorsivamente la prima parte
I si ordina ricorsivamente la seconda parte
I si combinano (operazione di fusione, merge ) le due parti ordinate
Esempio:
45
2
9
75
23
21
5
745
2
9
7
75
23
21
5
2
45
7
9
5
23
75
212
5
7
9
75
45
23
21
Divisione Fusione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 62
Il linguaggio C Algoritmi di ordinamento
Esprimiamo il procedimento in uno pseudo-linguaggio
ordina per fusione gli elementi di A da from a to
IF from < to (c’e piu di un elemento tra from e to)
THENmid = (from + to) /2ordina per fusione gli elementi di A da from a midordina per fusione gli elementi di A da mid +1 a tofondi
gli elementi di A da from a mid congli elementi di A da mid+1 a torestituendo il risultato nel sottovettore
di A da from a to
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 63
Il linguaggio C Algoritmi di ordinamento
Implementiamo l’algoritmo in C, definendo una procedura ricorsiva
void mergeRicorsivo(int A[], int from, int to)
che ordina la porzione dell’array A individuata dagli indici from e to.
void mergeRicorsivo(int A[], int from, int to)
{
int mid;
if (from < to) { /* l’intervallo da mid a to, estremi
inclusi, comprende almeno due elementi */
mid = (from + to) / 2;
mergeRicorsivo(A, from, mid);
mergeRicorsivo(A, mid+1, to);
merge(A, from, mid, to); /* fonde le due porzioni ordinate [from, mid],
[mid+1, to] nel sottovettore [from, to] */
}
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 64
Il linguaggio C Algoritmi di ordinamento
La procedura mergeSort che ordina un array di interi esemplicementevoid sort(int v[], int dim)
{
mergeRicorsivo(v, 0, dim-1);
}
Esempio:
45
2
9
75
23
21
5
7
75
23
21
5
45
7
9
2
23
75
21
5
2
45
7
9
75
23
5
21
7
45
9
2
23
75
5
21
2
45
7
9
5
23
75
212
5
7
9
75
45
23
21
45
2
9
7
FusioneDivisione
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 65
Il linguaggio C Algoritmi di ordinamento
I Vediamo l’operazione di fusione, definendo la procedura
void merge(int A[], int from, int mid, int to)
che fonde le due porzioni dell’array A con indici compresi tra from emid e tra mid+1 e to.
I La procedura utilizza un array di supporto B: per semplicita,supponiamo di avere una costante LUNG che definisce la lunghezzadegli array che stiamo trattando.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 66
Il linguaggio C Algoritmi di ordinamento
void merge(int A[], int from, int mid, int to)
{
int B[LUNG]; /* vettore di appoggio */
int primo, secondo, appoggio, da_copiare;
primo = from;
secondo = mid + 1;
appoggio = from;
while (primo <= mid && secondo <= to) { /* copia in modo ordinato */
if (A[primo] <= A[secondo]) { /* gli elementi della prima e */
B[appoggio] = A[primo]; /* della seconda porzione in B */
primo++; /* fino ad esaurire una delle due */
}
else {
B[appoggio] = A[secondo];
secondo++;
}
appoggio++;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 67
Il linguaggio C Algoritmi di ordinamento
if (secondo > to) /* e‘ finita prima la seconda porzione */
/* copia da A in B tutti gli elementi della
prima porzione fino a mid */
for (da_copiare = primo; da_copiare <= mid; da_copiare++) {
B[appoggio] = A[da_copiare];
appoggio++;
}
else /* e‘ finita prima la prima porzione */
for (da_copiare = secondo; da_copiare <= to; da_copiare++) {
/* copia da A in B tutti gli elementi della
/* seconda porzione fino a to */
B[appoggio] = A[da_copiare];
appoggio++;
}
/* ricopia tutti gli elementi da from a to da B ad A */
for (da_copiare = from; da_copiare <= to; da_copiare++)
A[da_copiare] = B[da_copiare];
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 68
Il linguaggio C Esercizi vari
Esercizio
I Si vuole scrivere un programma che:I legga il grado di un polinomio P a coefficienti interiI legga i coefficienti di PI calcoli il valore di P(x), con x acquisito in input
I Il primo problema e scegliere la struttura dati opportuna perrappresentare un polinomio generico: candidato naturale e lalista di coefficienti.
struct coefficiente {
int valore;
struct coefficiente *next;
}
typedef struct coefficiente Coefficiente;
typedef Coefficiente *Polinomio;
I Seguiamo un approccio top-down
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 69
Il linguaggio C Esercizi vari
main() {
int n = -1;
int coeff;
int i, x;
Polinomio poli = NULL;
do {
printf("Inserire il grado (> 0) di un polinomio: ");
scanf("%d", &n);
}
while (n<=0);
for(i=n; i>=0; i--)
{ printf("Inserire il coefficiente del termine di grado %d: ", i);
scanf("%d", &coeff);
InserisciInTesta(&poli, coeff);
}
/* Calcolo del polinomio */
printf("Inserire il punto sul quale calcolare P(x): ");
scanf("%d", &x);
printf("Valore di P(%d): %d\n", x, CalcoloPolinomio(poli, x));
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 70
Il linguaggio C Esercizi vari
I Definiamo le varie funzioni/procedure utilizzate
InserisciInTesta(Polinomio *, int) gia vista!
I Osserviamo che, per costruzione, i coefficienti sono in ordinecrescente di grado (prima il termine noto, poi il coefficiente digrado 1, ecc...)
int CalcoloPolinomio(Polinomio P, int x)
{
int risultato=0;
int grado = 0, coefficiente;
while (P != NULL)
{
coefficiente = P->info;
risultato = risultato + coefficiente * potenza(x, grado);
P = P->next;
grado = grado + 1;
}
return risultato;
}
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 71
Il linguaggio C Esercizi vari
Esercizi proposti Nel seguito si suppone definito il tipotypedef enum {false, true} boolean
1. Scrivere una funzione che verifichi che, in un array di interi vet didimensione dim, non vi siano elementi nulli in posizione pari.
2. Scrivere una funzione con prototipo
int occMax (int *vet, int dim)
che conta il numero di occorrenze dell’elemento massimo nell’arraydi interi vet di dimensione dim, possibilmente utilizzando al piu unciclo.
3. Scrivere una procedura che, dato un array di caratteri che contienesolo lettere alfabetiche, li ridispone nell’array medesimo in modo chetutte le lettere maiuscole occorrano prima di tutte le lettereminuscole.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 72
Il linguaggio C Esercizi vari
4. Scrivere una funzione a valori booleani che verifichi la seguenteproprieta di un vettore di interi: ogni elemento nella meta di destradel vettore e maggiore di ogni elemento nella meta sinistra delvettore. Attenzione: non si possono utilizzare vetori di supporto, nemodificare l’array dato.
5. Definire una funzione con prototipo
boolean foo(int *a, int n)
che restituisce true se ogni elemento pari dell’array a, di lunghezzan, e immediatamente seguito, nell’array stesso, da un elementodispari; restituisce false altrimenti. Fornire sia una versioneiterativa che una versione ricorsiva.
6. Definire una funzione ricorsiva con prototipo
int foo (int n)
che calcola il valore 2k , dove k ‘e il numero di occorrenze della cifra1 nella rappresentazione decimale di n. Si assume che il valore delparametro n sia un intero non negativo. Ad esempio, la chiamatafoo(32121) deve restituire 22 = 4, mentre la chiamatafoo(42628) deve restituire 20 = 1.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 73
Il linguaggio C Esercizi vari
7. Definire una funzione ricorsiva con prototipo
boolean sumPari(int n)
che restituisce true se la somma delle cifre nella rappresentazionedi n in base 10 e pari; restituisce false altrimenti.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 74
Il linguaggio C Esercizi su liste
Negli esercizi che seguono si suppongono date le seguenti definizioni ditipo
struct El {
int info;
struct El *next;
}
typedef struct El ElementoListaInt;
typedef ElementoListaInt *ListaDiInteri;
/* Si suppone che Tipo sia definito altrove */
struct ElTipo {
Tipo info;
struct ElTipo *next;
}
typedef struct ElTipo ElementoListaTipo;
typedef ElementoListaTipo *ListaDiTipo;
1. Definire una funzione che, data una ListaDiTipo, restituisce la sualunghezza.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 75
Il linguaggio C Esercizi su liste
2. Definire una funzione FirstEven che, data una ListaDiInteri,restituisce la posizione (puntatore) del primo elemento pari nellalista (restituisce NULL se la lista non contiene elementi pari).
3. Definire una funzione MinEven che, data una ListaDiInteri,restituisce la posizione (puntatore) del minimo elemento pari nellalista (restituisce NULL se la lista non contiene elementi pari).
4. Definire una procedura foo che, data una ListaDiInteri lista edun intero el, inserisce el dopo il terzo elemento di lista. Quest’ultimaviene lasciata inalterata se non contiene almeno tre elementi.
5. Definire una procedura foo che, data una ListaDiInteri lista edun intero el, inserisce el dopo il terzo elemento di lista. Sequest’ultima non contiene almeno tre elementi, el viene inserito intesta.
6. Definire una procedura foo che, data una ListaDiInteri lista edun intero el, inserisce el dopo l’ultimo elemento di lista maggiore diel. Se lista non contiene alcun elemento maggiore di el, la proceduralo inserisce in ultima posizione.
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 76
Il linguaggio C Esercizi su liste
7. Definire una procedura EliminaXel che, data una ListaDiTipo,elimini i primi x elementi. Ad esempio, data la lista di caratteri
--> 2 --> 7 --> 7 --> 9 --> 9
e x uguale a 2 la procedura modifica la lista come segue:
--> 7 --> 9 --> 9
prof. P. Mancarella – Dip.to Informatica INFORMATICA 1 a.a. 07/08 - esercitazioni – pag. 77
INFORMATICA 1 - CdL in FISICA
Esercitazione del 23/05/2008
ESERCIZIO 1Definire il prototipo della funzione foo in modo che la sua chiamata all’interno del seguente frammento di codicerisulti corretta a tempo di compilazione.
main(){int *p, x;char c;p = &x;c = foo(*p, &c, &p);...
}
ESERCIZIO 2Definire una funzione ricorsiva che, dato un intero n, legge una sequenza di interi terminata da 0 e calcola lasomma degli elementi nella sequenza che sono minori di n.
ESERCIZIO 3Definire una funzione con prototipo
boolean check (int *v1, int dim1, int *v2, int dim2)che verifica, per ogni elemento x nel vettore v1 di dimensione dim1, la presenza di un multiplo di x nel vettore v2di dimensione dim2.
ESERCIZIO 4Si vuole rappresentare un multinsieme finito di caratteri mediante una sequenza di coppie (ch, n) dove ch e uncarattere e n il numero di occorrenze di ch nel multinsieme, con n > 0. Ad esempio il multinsieme{
’a’, ’b’, ’a’, ’a’, ’c’}
e rappresentato dalla sequenza〈 (’a’,3), (’b’,1) , (’c’,1) 〉.
Dopo aver definito i tipi opportuni per la rappresentazione indicata, si scriva una procedura che, dato un multinsiemeM ed un carattere ch, inserisce ch in M. Se ch non e gia presente in M, la procedura dovra inserirlo in testa allasequenza.Ad esempio, dato il multinsieme M rappresentato dalla sequenza precedente, l’inserzione di ’b’ in M modificaquest’ultimo nella sequenza
〈 (’a’,3), (’b’,2) , (’c’,1) 〉,mentre l’inserzione di ′f′ in M modifica quest’ultimo in
〈 (’f ’,1), (’a’,3), (’b’,1), (’c’,1)〉.