31.05.2013 Views

tipi derivati - Dipartimento di Informatica ed Applicazioni

tipi derivati - Dipartimento di Informatica ed Applicazioni

tipi derivati - Dipartimento di Informatica ed Applicazioni

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Tipi <strong>di</strong> Dato Derivati<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Un tipo <strong>di</strong> dato derivato è ottenuto a<br />

partire da <strong>tipi</strong> <strong>di</strong> dato pr<strong>ed</strong>efiniti<br />

attraverso gli operatori *, &, []<br />

definendo enumerazioni<br />

definendo struct<br />

I <strong>tipi</strong> <strong>di</strong> dato <strong>derivati</strong> non sono <strong>tipi</strong> <strong>di</strong> dati<br />

nuovi, ma semplice composizione <strong>di</strong> <strong>tipi</strong> <strong>di</strong><br />

dati esistenti<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 1<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

1


Array<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Un array è un insieme <strong>di</strong> oggetti dello stesso tipo<br />

referenziati da un unico identificatore<br />

Gli oggetti dell’array sono referenziati tramite<br />

l’identificatore dell’array e la loro posizione nell’insieme<br />

(in<strong>di</strong>cizzazione)<br />

int ia[10]; // ia è un vettore <strong>di</strong> 10 interi<br />

int i = ia[2]; // copia il terzo elemento <strong>di</strong> ia in i<br />

ia[7] = i; // copia i sull'’ottavo elemento <strong>di</strong> ia<br />

La <strong>di</strong>mensione dell’array può essere qualsiasi<br />

espressione costante<br />

non può essere variabile<br />

In<strong>di</strong>cizzazione <strong>di</strong> un Array<br />

Le posizioni degli oggetti in un array si contano da 0<br />

Il compilatore non effettua nessun controllo sulla<br />

correttezza dell’in<strong>di</strong>cizzazione<br />

char c[7];<br />

c[7] = `Y’; // scrive Y nell’ottavo elemento <strong>di</strong> c<br />

In<strong>di</strong>cizzazione errata implica un accesso ad aree <strong>di</strong><br />

memoria non allocate all’array<br />

Può provocare errori in esecuzione (segmentation<br />

fault)<br />

Può <strong>di</strong>struggere i dati del programma<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 2<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

2<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

3


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Inizializzazione <strong>di</strong> un Array<br />

L’array è inizializzato dando la lista dei valori<br />

int ia[3] = {0, 1, 2};<br />

Se il vettore è inizializzato si può non specificare la<br />

<strong>di</strong>mensione<br />

int ia[] = {0, 1, 2};<br />

E’ possibile inizializzare parzialmente un array<br />

int ia[3] = {1};<br />

// ia[0] = 1, gli altri elementi valgono 0<br />

Array <strong>di</strong> char<br />

E’ possibile inizializzare un array <strong>di</strong> char<br />

con una stringa costante<br />

Una stringa è un array <strong>di</strong> char con il simbolo<br />

finale `\0’<br />

const char ca[] = {`C’, `+’, `+’}; // ca lungo 3<br />

const char ca[] = “C++”; // ca lungo 4<br />

const char ca[5] = “prova”; // ERRORE<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 3<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

4<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

5


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Operazioni su Array<br />

Non è possibile inizializzare o assegnare un array ad un<br />

altro array<br />

int ia[] = {1, 2, 3};<br />

int ia2[] = ia; // ERRORE<br />

Se si vuole copiare un array bisogna copiare un<br />

elemento per volta<br />

for(int i = 0; i


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Inizializzazione <strong>di</strong> Array<br />

Multi<strong>di</strong>mensionali<br />

Un array bi<strong>di</strong>mensionale è un array <strong>di</strong> array<br />

ogni array inizializzato separatamente<br />

int ia[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}};<br />

int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};<br />

E’ possibile inizializzare parzialmente un<br />

array multi<strong>di</strong>mensionale<br />

int ia[3][4] = {0, 1, 2, 3};<br />

int ia[3][4] = {{0}, {4}, {8}};<br />

Accesso a Array Multi<strong>di</strong>mensionali<br />

Per acc<strong>ed</strong>ere ad un elemento <strong>di</strong> un array<br />

multi<strong>di</strong>mensionale bisogna specificare ogni<br />

in<strong>di</strong>ce in una parentesi quadra<br />

int i = ia[2][3];<br />

i = ia[2, 3]; // ERRORE<br />

cosa fa in realtà l'istruzione errata?<br />

assegna ia[3] ad i<br />

ia[3] è un array<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 5<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

8<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

9


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Relazione tra Array e Puntatori<br />

Alla definizione <strong>di</strong> un array il compilatore alloca<br />

spazio per contenere tutti gli elementi dell’array<br />

e definisce un puntatore inizializzato con<br />

l’in<strong>di</strong>rizzo del primo byte allocato<br />

char ac[5];<br />

nome tipo in<strong>di</strong>r.<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

ac<br />

Tipo <strong>di</strong> un Array<br />

char*<br />

Il tipo <strong>di</strong> un array è puntatore al tipo degli<br />

oggetti dell’array<br />

Ogni operazione <strong>di</strong> in<strong>di</strong>cizzazione è<br />

implementata attraverso l’aritmetica dei<br />

puntatori<br />

ia[4] = 3; // implementata come *(ia + 4) = 3<br />

m[1][2] = 0; /* implementata come<br />

*(*(m + 1) + 2) = 0 */<br />

2001/02 6<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

10<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

11


Tipo <strong>di</strong> un Array<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

L’identificatore dell’array si comporta<br />

come un puntatore costante<br />

E’ sempre possibile assegnare un array<br />

ad un puntatore dello stesso tipo<br />

char buffer[256];<br />

char *p = buffer;<br />

// p in<strong>di</strong>rizza il primo elemento <strong>di</strong> buffer<br />

Non è possibile assegnare un puntatore ad un<br />

array<br />

buffer = p; // ERRORE<br />

Differenze tra Array e Puntatori<br />

La definizione <strong>di</strong> un array implica allocazione <strong>di</strong><br />

memoria per tutti gli oggetti dell’array e per il<br />

puntatore che li in<strong>di</strong>rizza<br />

La definizione <strong>di</strong> un puntatore implica<br />

allocazione <strong>di</strong> memoria per un in<strong>di</strong>rizzo<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 7<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

12<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

13


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Il Contenitore vector<br />

La classe vector della libreria standard è una valida<br />

alternativa agli array stile C<br />

#include // include definizione classe vector<br />

Differenze tra vector e array<br />

È possibile definire vector <strong>di</strong> <strong>di</strong>mensione variabile<br />

è possibile mo<strong>di</strong>ficare le <strong>di</strong>mensioni <strong>di</strong> un vector<br />

Non è possibile inizializzare esplicitamente oggetti vector<br />

È possibile assegnare un vector ad un altro vector<br />

Esistono operazioni su vector<br />

Definizione <strong>di</strong> oggetti vector<br />

vector a;<br />

/* Definisce un vettore <strong>di</strong> tipo T il cui<br />

identificatore è a e la cui <strong>di</strong>mensione è 0 */<br />

vector a(5); // equivale a T a[5];<br />

// Definisce un vettore <strong>di</strong> tipo T <strong>di</strong> 5 elementi<br />

vector a(5, 4); // equivale a T a[] = {4, 4, 4, 4, 4}<br />

/* Definisce un vettore <strong>di</strong> tipo T <strong>di</strong> 5 elementi<br />

inizializzati con 4 */<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 8<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

14<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

15


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Accesso a elementi <strong>di</strong> vector<br />

L'accesso al vector può essere fatto tramite<br />

l'operatore []<br />

Simile all'accesso agli array<br />

#include <br />

vector vec(10);<br />

for(int i = 1; i


Iteratori<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

L'iteratore è una classe che implementa l'astrazione del<br />

puntatore<br />

operazioni ammissibili =, *, ++, --<br />

ogni contenitore ha la propria implementazione <strong>di</strong> iteratore,<br />

definita all'interno della classe<br />

Ogni contenitore fornisce meto<strong>di</strong> per recuperare in<strong>di</strong>rizzi<br />

<strong>di</strong> suoi elementi tramite iteratori<br />

è possibile acc<strong>ed</strong>ere e scorrere gli elementi <strong>di</strong> tutti i contenitori<br />

alla stessa maniera<br />

vector::begin(); // primo elemento <strong>di</strong> vector<br />

vector::end(); // elemento successivo all’ultimo<br />

Alcuni meto<strong>di</strong> della classe vector<br />

empty() // restituisce vero se il vettore è vuoto<br />

size() // restituisce # <strong>di</strong> elementi nel vettore<br />

capacity() // restituisce la grandezza del vettore<br />

resize(N) // la nuova <strong>di</strong>mensione del vettore è N<br />

push_back(x) // aggiunge x alla fine del vettore<br />

pop_back() // elimina l’ultimo elemento del vettore<br />

per utilizzare i meto<strong>di</strong> della classe vector si usa l'operatore <strong>di</strong><br />

selezione<br />

vector v;<br />

v.metodo();<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 10<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

18<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

19


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Ri<strong>di</strong>mensionamento <strong>di</strong>namico <strong>di</strong><br />

vector<br />

un oggetto vector può essere allungato <strong>di</strong>namicamente<br />

senza allocare esplicitamente la memoria<br />

#include <br />

#include <br />

vector testo;<br />

string parola;<br />

while(cin >> parola) testo.push_back(parola);<br />

cout


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Esempio uso vector<br />

#include <br />

#include <br />

#include <br />

main() {<br />

int ia[10] = {51, 23, 7, 88, 41, 98, 12, 103, 37, 6}, x;<br />

vector vec(ia, ia+10);<br />

sort(vec.begin(), vec.end());<br />

reverse(vec.begin(), vec.end());<br />

cin >> x;<br />

vector::iterator trovato;<br />

trovato = find(vec.begin(), vec.end(), x);<br />

if(trovato != vec.end())<br />

cout


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Esempio Stringhe<br />

Calcolare la lunghezza della stringa “ciao mondo\n”<br />

#include <br />

char *st = “ciao mondo\n”;<br />

int main() {<br />

int lung = 0;<br />

char *p = st;<br />

while( *p != `\0’ ) {<br />

lung = lung + 1;<br />

p = p+1;<br />

}<br />

cout


Il Tipo string<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

La libreria standard fornisce una nuova<br />

implementazione delle stringhe come classe<br />

Principali <strong>di</strong>fferenze<br />

Inizializzare una stringa con un'altra stringa<br />

Copia <strong>di</strong> stringhe<br />

Accesso ai singoli elementi della stringa<br />

Operazioni <strong>di</strong> confronto tra stringhe<br />

Operazioni <strong>di</strong> concatenazione e calcolo lunghezza<br />

Operazioni <strong>di</strong> manipolazione stringhe<br />

Controllo stringa vuota<br />

Conversione a stringa C-style<br />

Esempio uso <strong>di</strong> string<br />

Calcolare la lunghezza della stringa “ciao mondo\n”<br />

#include <br />

#include <br />

string st = “ciao mondo\n”;<br />

int main() {<br />

int lung = st.size();<br />

cout


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Alcuni meto<strong>di</strong> della classe string<br />

bool empty()<br />

// restituisce vero se la stringa è vuota<br />

int size()<br />

// restituisce # <strong>di</strong> caratteri nella stringa<br />

string operator+(const string&)<br />

string operator+=(const string&)<br />

// concatena due stringhe<br />

const char* c_str()<br />

// converte la stringa in stile C<br />

Enumerazioni<br />

Un’enumerazione è un insieme <strong>di</strong> costanti simboliche<br />

intere<br />

Insieme <strong>di</strong> attributi da associare ad un oggetto<br />

enum stato { caldo, fr<strong>ed</strong>do };<br />

// caldo = 0, fr<strong>ed</strong>do = 1;<br />

Gli enumeratori non sono singolarmente in<strong>di</strong>rizzabili<br />

non si può applicare l’operatore (&) ad un enumeratore<br />

Definizione <strong>di</strong> un’enumerazione<br />

enum colore { giallo, rosso, verde = 1, bianco };<br />

// giallo = 0, rosso = 1, verde = 1, bianco = 2<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 15<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

28<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

29


Enumerazioni<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

E’ possibile definire una variabile del tipo definito da<br />

un’enumerazione<br />

colore vernice = giallo;<br />

//vernice può assumere solo i valori<br />

giallo, rosso, verde e bianco<br />

Non è possibile assegnare valori interi ad una variabile<br />

<strong>di</strong> tipo enumerazione<br />

E' possibile assegnare una variabile <strong>di</strong> tipo<br />

enumerazione ad una variabile int<br />

vernice = giallo; // giallo contiene il valore 0<br />

vernice = 0; // ERRORE<br />

int i = vernice; // i = 0<br />

Tipo bool<br />

Una variabile <strong>di</strong> tipo bool può assumere<br />

come valori solo i valori true e false<br />

bool trovato = false;<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 16<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

30<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

31


Struct<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Uno struct è un insieme <strong>di</strong> oggetti, non<br />

necessariamente dello stesso tipo, memorizzati<br />

sequenzialmente <strong>ed</strong> identificati da un unico nome<br />

Gli elementi <strong>di</strong> uno struct sono referenziati attraverso<br />

l’identificatore dello struct <strong>ed</strong> il loro specifico<br />

identificatore attraverso gli operatori <strong>di</strong> selezione (.) e<br />

(->)<br />

Classi<br />

struct record {<br />

string nome, cognome, in<strong>di</strong>rizzo;<br />

int eta;<br />

};<br />

record <strong>di</strong>pendente;<br />

<strong>di</strong>pendente.nome = “mario”;<br />

La classe è una generalizzazione dello struct<br />

Insieme <strong>di</strong> oggetti e funzioni (meto<strong>di</strong>) che operano su questi<br />

oggetti<br />

Ogni elemento <strong>di</strong> una classe ha un livello <strong>di</strong> visibilità<br />

Una funzione può acc<strong>ed</strong>ere soltanto agli elementi <strong>di</strong> visibilità<br />

public <strong>di</strong> oggetti della classe<br />

Per ogni classe si definisce un’interfaccia pubblica che<br />

consente <strong>di</strong> interagire con oggetti <strong>di</strong> quella classe<br />

l’interfaccia pubblica è un insieme <strong>di</strong> meto<strong>di</strong> che hanno visibilità<br />

public<br />

La classe implementa il concetto <strong>di</strong> Abstract Data Type<br />

string e vector sono classi<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 17<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

32<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

33


Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Esempio <strong>di</strong> classe String<br />

class String {<br />

public:<br />

String(); // String str;<br />

String(const char *); // String str("ciao");<br />

String(const String&); // String str1 = str;<br />

~String();<br />

String& operator=(const String&);<br />

bool operator==(const String&);<br />

char& operator[](int);<br />

int size();<br />

char* c_str();<br />

private:<br />

int <strong>di</strong>m;<br />

char *arr;<br />

};<br />

Typ<strong>ed</strong>ef<br />

L’operatore typ<strong>ed</strong>ef consente <strong>di</strong> assegnare un<br />

identificatore ad un tipo <strong>di</strong> dato derivato<br />

Il typ<strong>ed</strong>ef non crea un nuovo tipo <strong>di</strong> dato<br />

typ<strong>ed</strong>ef char* stringa;<br />

Il tipo definito dal typ<strong>ed</strong>ef può essere utilizzato come<br />

specificatore <strong>di</strong> tipo in una definizione o <strong>di</strong>chiarazione<br />

stringa c = “ciao”;<br />

Il typ<strong>ed</strong>ef è usato per <strong>di</strong>minuire la complessità<br />

notazionale delle definizioni<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 18<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

34<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

35


Variabili Volatili<br />

Lezione 3<br />

Tipi <strong>di</strong> Dato Derivati<br />

Una variabile è <strong>di</strong>chiarata volatile se il suo valore<br />

può cambiare al <strong>di</strong> fuori del controllo del<br />

programma<br />

Variabili che leggono il time dal sistema<br />

Il compilatore deve evitare <strong>di</strong> applicare tecniche<br />

<strong>di</strong> ottimizzazione del co<strong>di</strong>ce a queste variabili<br />

volatile int time;<br />

volatile char* buffer;<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati<br />

2001/02 19<br />

Laboratorio <strong>di</strong> Algoritmi e Strutture Dati 2001-02<br />

36

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!