Lezione 3 Tipi di Dato Derivati Tipi di Dato Derivati Lezione 3 ü Un tipo di dato derivato è ottenuto a partire da tipi di dato predefiniti attraverso gli operatori *, &, [] ® definendo enumerazioni ® definendo struct ® ü I tipi di dato derivati non sono tipi di dati nuovi, ma semplice composizione di tipi di dati esistenti Laboratorio di Algoritmi e Strutture Dati 2001 -02 Tipi di Dato Derivati 1 Laboratorio di Algoritmi e Strutture Dati 2001/02 1 Lezione 3 Tipi di Dato Derivati ü Un array è un insieme di oggetti dello stesso tipo referenziati da un unico identificatore ü Gli oggetti dell’array sono referenziati tramite l’identificatore dell’array e la loro posizione nell’insieme (indicizzazione) int ia[10]; // ia è un vettore di 10 interi int i = ia[2]; // copia il terzo elemento di ia in i ia[7] = i; // copia i sull'’ottavo elemento di ia ü La dimensione dell’array può essere qualsiasi espressione costante ® non può essere variabile Laboratorio di Algoritmi e Strutture Dati 2001 -02 Array 2 ü Le posizioni degli oggetti in un array si contano da 0 ü Il compilatore non effettua nessun controllo sulla correttezza dell’indicizzazione char c[7]; c[7] = `Y’; // scrive Y nell’ottavo elemento di c ü Indicizzazione errata implica un accesso ad aree di memoria non allocate all’array ® Può provocare errori in esecuzione (segmentation fault) ® Può distruggere i dati del programma Laboratorio di Algoritmi e Strutture Dati 2001 -02 Indicizzazione di un Array 3 Laboratorio di Algoritmi e Strutture Dati 2001/02 2 Lezione 3 Tipi di Dato Derivati ü L’array è inizializzato dando la lista dei valori int ia[3] = {0, 1, 2}; ü Se il vettore è inizializzato si può non specificare la dimensione int ia[] = {0, 1, 2}; ü E’ possibile inizializzare parzialmente un array int ia[3] = {1}; // ia[0] = 1, gli altri elementi valgono 0 Laboratorio di Algoritmi e Strutture Dati 2001 -02 Inizializzazione di un Array 4 ü E’ possibile inizializzare un array di char con una stringa costante ® Una stringa è un array di char con il simbolo finale `\0’ const char ca[] = {`C’, `+’, `+’}; const char ca[] = “C++”; const char ca[5] = “prova”; // ca lungo 3 // ca lungo 4 // ERRORE Laboratorio di Algoritmi e Strutture Dati 2001 -02 Array di char 5 Laboratorio di Algoritmi e Strutture Dati 2001/02 3 Lezione 3 Tipi di Dato Derivati ü Non è possibile inizializzare o assegnare un array ad un altro array int ia[] = {1, 2, 3}; int ia2[] = ia; // ERRORE ü Se si vuole copiare un array bisogna copiare un elemento per volta for(int i = 0; i<3; i++) ia2[i] = ia[i]; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operazioni su Array 6 ü Si definisce un array multidimensionale specificando ogni dimensione tra parentesi quadre char a[3][4]; // matrice di 3 righe e 4 colonne ü Un array bidimensionale è un array di array a a[0] a[1] a[2] Laboratorio di Algoritmi e Strutture Dati 2001 -02 Array Multidimensionali 7 Laboratorio di Algoritmi e Strutture Dati 2001/02 4 Lezione 3 Tipi di Dato Derivati ü Un array bidimensionale è un array di array ® ogni array inizializzato separatamente int ia[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}; int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; ü E’ possibile inizializzare parzialmente un array multidimensionale int ia[3][4] = {0, 1, 2, 3}; int ia[3][4] = {{0}, {4}, {8}}; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Inizializzazione di Array Multidimensionali 8 ü Per accedere ad un elemento di un array multidimensionale bisogna specificare ogni indice in una parentesi quadra int i = ia[2][3]; i = ia[2, 3]; // ERRORE ü cosa fa in realtà l'istruzione errata? ®assegna ia[3] ad i Laboratorio di Algoritmi e Strutture Dati 2001 -02 Accesso a Array Multidimensionali ®ia[3] è un array 9 Laboratorio di Algoritmi e Strutture Dati 2001/02 5 Lezione 3 Tipi di Dato Derivati ü Alla definizione di un array il compilatore alloca spazio per contenere tutti gli elementi dell’array e definisce un puntatore inizializzato con l’indirizzo del primo byte allocato char ac[5]; nome ac tipo indir. char* Laboratorio di Algoritmi e Strutture Dati 2001 -02 Relazione tra Array e Puntatori 10 ü Il tipo di un array è puntatore al tipo degli oggetti dell’array ü Ogni operazione di indicizzazione è implementata attraverso l’aritmetica dei puntatori ia[4] = 3; m[1][2] = 0; // implementata come *(ia + 4) = 3 /* implementata come *(*(m + 1) + 2) = 0 */ Laboratorio di Algoritmi e Strutture Dati 2001 -02 Tipo di un Array 11 Laboratorio di Algoritmi e Strutture Dati 2001/02 6 Lezione 3 Tipi di Dato Derivati Tipo di un Array come un puntatore costante ü E’ sempre possibile assegnare un array ad un puntatore dello stesso tipo char buffer[256]; char *p = buffer; // p indirizza il primo elemento di buffer ü Non è possibile assegnare un puntatore ad un array buffer = p; Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü L’identificatore dell’array si comporta // ERRORE 12 ü La definizione di un array implica allocazione di memoria per tutti gli oggetti dell’array e per il puntatore che li indirizza ü La definizione di un puntatore implica allocazione di memoria per un indirizzo Laboratorio di Algoritmi e Strutture Dati 2001 -02 Differenze tra Array e Puntatori 13 Laboratorio di Algoritmi e Strutture Dati 2001/02 7 Lezione 3 Tipi di Dato Derivati ü La classe vector della libreria standard è una valida alternativa agli array stile C #include <vector> // include definizione classe vector ü Differenze tra vector e array ® È possibile definire vector di dimensione variabile ® è possibile modificare le dimensioni di un vector ® Non è possibile inizializzare esplicitamente oggetti vector ® È possibile assegnare un vector ad un altro vector ® Esistono operazioni su vector Laboratorio di Algoritmi e Strutture Dati 2001 -02 Il Contenitore vector 14 vector<T> a; /* Definisce un vettore di tipo T il cui identificatore è a e la cui dimensione è 0 */ vector<T> a(5); // equivale a T a[5]; // Definisce un vettore di tipo T di 5 elementi vector<T> a(5, 4); // equivale a T a[] = {4, 4, 4, 4, 4} /* Definisce un vettore di tipo T di 5 elementi inizializzati con 4 */ Laboratorio di Algoritmi e Strutture Dati 2001 -02 Definizione di oggetti vector 15 Laboratorio di Algoritmi e Strutture Dati 2001/02 8 Lezione 3 Tipi di Dato Derivati ü L'accesso al vector può essere fatto tramite l'operatore [] ® Simile all'accesso agli array #include <vector> vector<int> vec(10); for(int i = 1; i <= 10; ++i) vec[i] = i; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Accesso a elementi di vector 16 ü E' possibile accedere agli elementi del vector in maniera indipendente dalla rappresentazione della classe ® stessa tecnica per accedere ad ogni tipo di classe contenitore #include <vector> vector<int> vec(10); vector<int>::iterator it = vec.begin(); for(int i = 0; it != vec.end(); ++i, ++it) *it = i; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Accesso a elementi di vector stile STL 17 Laboratorio di Algoritmi e Strutture Dati 2001/02 9 Lezione 3 Tipi di Dato Derivati ü L'iteratore è una classe che implementa l'astrazione del puntatore ® ® operazioni ammissibili =, *, ++, -ogni contenitore ha la propria implementazione di iteratore, definita all'interno della classe ü Ogni contenitore fornisce metodi per recuperare indirizzi di suoi elementi tramite iteratori ® è possibile accedere e scorrere gli elementi di tutti i contenitori alla stessa maniera vector<T>::begin(); // primo elemento di vector vector<T>::end(); // elemento successivo all’ultimo Laboratorio di Algoritmi e Strutture Dati 2001 -02 Iteratori 18 empty() // restituisce vero se il vettore è vuoto size() // restituisce # di elementi nel vettore capacity() // restituisce la grandezza del vettore resize(N) // la nuova dimensione del vettore è N push_back(x) // aggiunge x alla fine del vettore pop_back() // elimina l’ultimo elemento del vettore ü per utilizzare i metodi della classe vector si usa l'operatore di selezione vector<int> v; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Alcuni metodi della classe vector v.metodo(); 19 Laboratorio di Algoritmi e Strutture Dati 2001/02 10 Lezione 3 Tipi di Dato Derivati ü un oggetto vector può essere allungato dinamicamente ® senza allocare esplicitamente la memoria #include <vector> #include <iostream> vector<string> testo; string parola; while(cin >> parola) testo.push_back(parola); cout << "Le parole lette sono:" << endl; for(vector<string>::iterator it = testo.begin(); it != testo.end(); ++it) cout << *it << ' '; cout << endl; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Ridimensionamento dinamico di vector 20 ü La libreria standard fornisce una serie di algoritmi generici per operare su qualsiasi tipo di contenitore ® algoritmi di ricerca ed ordinamento w find(), find_if(), search(), binary_search(), count(), count_if() w sort(), merge(), partition(), reverse(), rotate(), random_shuffle() ® algoritmi di creazione e cancellazione w generate(), fill(), transform(), copy(), for_each(), w remove(), unique() ® algoritmi relazionali e numerici w equal(), min(), max() w partial_sum(), inner_product(), accumulate(), Laboratorio di Algoritmi e Strutture Dati 2001 -02 Algoritmi su vector adjacent_differences() 21 Laboratorio di Algoritmi e Strutture Dati 2001/02 11 Lezione 3 Tipi di Dato Derivati #include <vector> #include <algorithm> #include <iostream> main() { int ia[10] = {51, 23, 7, 88, 41, 98, 12, 103, 37, 6}, x; vector<int> vec(ia, ia+10); sort(vec.begin(), vec.end()); reverse(vec.begin(), vec.end()); cin >> x; vector<int>::iterator trovato; trovato = find(vec.begin(), vec.end(), x); if(trovato != vec.end()) cout << "valore trovato" << endl; else cout << "valore non presente" << endl; } Laboratorio di Algoritmi e Strutture Dati 2001 -02 Esempio uso vector 22 ü Una stringa (stile C) è un array di caratteri indirizzato attraverso un puntatore ® Il tipo di una stringa è char* char *s = “ciao mondo\n”; ü Una stringa è rappresentata in memoria da una sequenza di caratteri seguiti dal segnale di fine stringa (`\0’) Laboratorio di Algoritmi e Strutture Dati 2001 -02 Stringhe 23 Laboratorio di Algoritmi e Strutture Dati 2001/02 12 Lezione 3 Tipi di Dato Derivati Esempio Stringhe #include <iostream> char *st = “ciao mondo\n”; int main() { int lung = 0; char *p = st; while( *p != `\0’ ) { lung = lung + 1; p = p+1; } cout << “lunghezza di “ << st << “ = “ << lung; return 0; } Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Calcolare la lunghezza della stringa “ciao mondo\n” 24 ü La libreria standard del C fornisce funzioni per effettuare alcune operazioni su stringhe #include <cstring> int strlen(const char* s); // calcola lunghezza di s int strcmp(const char* s, const char* t); // controlla se s e t sono uguali int strcpy(const char* s, const char* t); // copia t su s Laboratorio di Algoritmi e Strutture Dati 2001 -02 Operazioni sulle Stringhe 25 Laboratorio di Algoritmi e Strutture Dati 2001/02 13 Lezione 3 Tipi di Dato Derivati ü La libreria standard fornisce una nuova implementazione delle stringhe come classe ü Principali differenze ® ® ® ® ® ® ® ® Inizializzare una stringa con un'altra stringa Copia di stringhe Accesso ai singoli elementi della stringa Operazioni di confronto tra stringhe Operazioni di concatenazione e calcolo lunghezza Operazioni di manipolazione stringhe Controllo stringa vuota Conversione a stringa C-style Laboratorio di Algoritmi e Strutture Dati 2001 -02 Il Tipo string 26 ü Calcolare la lunghezza della stringa “ciao mondo\n” #include <iostream> #include <string> string st = “ciao mondo\n”; int main() { int lung = st.size(); cout << “lunghezza di “ << st << “ = “ << lung; return 0; } Laboratorio di Algoritmi e Strutture Dati 2001 -02 Esempio uso di string 27 Laboratorio di Algoritmi e Strutture Dati 2001/02 14 Lezione 3 Tipi di Dato Derivati bool empty() // restituisce vero se la stringa è vuota int size() // restituisce # di caratteri nella stringa string operator+(const string&) string operator+=(const string&) // concatena due stringhe const char* c_str() // converte la stringa in stile C Laboratorio di Algoritmi e Strutture Dati 2001 -02 Alcuni metodi della classe string 28 ü Un’enumerazione è un insieme di costanti simboliche intere ® Insieme di attributi da associare ad un oggetto enum stato { caldo, freddo }; // caldo = 0, freddo = 1; ü Gli enumeratori non sono singolarmente indirizzabili ® non si può applicare l’operatore (&) ad un enumeratore ü Definizione di un’enumerazione enum colore { giallo, rosso, verde = 1, bianco }; // giallo = 0, rosso = 1, verde = 1, bianco = 2 Laboratorio di Algoritmi e Strutture Dati 2001 -02 Enumerazioni 29 Laboratorio di Algoritmi e Strutture Dati 2001/02 15 Lezione 3 Tipi di Dato Derivati Enumerazioni un’enumerazione colore vernice = giallo; //vernice può assumere solo i valori giallo, rosso, verde e bianco ü Non è possibile assegnare valori interi ad una variabile di tipo enumerazione ü E' possibile assegnare una variabile di tipo enumerazione ad una variabile int vernice = giallo; // giallo contiene il valore 0 vernice = 0; // ERRORE int i = vernice; // i = 0 Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü E’ possibile definire una variabile del tipo definito da 30 ü Una variabile di tipo bool può assumere come valori solo i valori true e false bool trovato = false; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Tipo bool 31 Laboratorio di Algoritmi e Strutture Dati 2001/02 16 Lezione 3 Tipi di Dato Derivati Struct necessariamente dello stesso tipo, memorizzati sequenzialmente ed identificati da un unico nome ü Gli elementi di uno struct sono referenziati attraverso l’identificatore dello struct ed il loro specifico identificatore attraverso gli operatori di selezione (.) e (->) struct record { string nome, cognome, indirizzo; int eta; }; record dipendente; dipendente.nome = “mario”; Laboratorio di Algoritmi e Strutture Dati 2001 -02 ü Uno struct è un insieme di oggetti, non 32 ü La classe è una generalizzazione dello struct ® Insieme di oggetti e funzioni (metodi) che operano su questi oggetti ü Ogni elemento di una classe ha un livello di visibilità ® Una funzione può accedere soltanto agli elementi di visibilità public di oggetti della classe ü Per ogni classe si definisce un’interfaccia pubblica che consente di interagire con oggetti di quella classe ® l’interfaccia pubblica è un insieme di metodi che hanno visibilità public ü La classe implementa il concetto di Abstract Data Type ® Laboratorio di Algoritmi e Strutture Dati 2001 -02 Classi string e vector<T> sono classi 33 Laboratorio di Algoritmi e Strutture Dati 2001/02 17 Lezione 3 Tipi di Dato Derivati class String { public: String(); // String str; String(const char *); // String str("ciao"); String(const String&); // String str1 = str; ~String(); String& operator=(const String&); bool operator==(const String&); char& operator[](int); int size(); char* c_str(); private: int dim; char *arr; }; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Esempio di classe String 34 ü L’operatore typedef consente di assegnare un identificatore ad un tipo di dato derivato ® Il typedef non crea un nuovo tipo di dato typedef char* stringa; ü Il tipo definito dal typedef può essere utilizzato come specificatore di tipo in una definizione o dichiarazione stringa c = “ciao”; ü Il typedef è usato per diminuire la complessità notazionale delle definizioni Laboratorio di Algoritmi e Strutture Dati 2001 -02 Typedef 35 Laboratorio di Algoritmi e Strutture Dati 2001/02 18 Lezione 3 Tipi di Dato Derivati ü Una variabile è dichiarata volatile se il suo valore può cambiare al di fuori del controllo del programma ® Variabili che leggono il time dal sistema ü Il compilatore deve evitare di applicare tecniche di ottimizzazione del codice a queste variabili volatile int time; volatile char* buffer; Laboratorio di Algoritmi e Strutture Dati 2001 -02 Variabili Volatili 36 Laboratorio di Algoritmi e Strutture Dati 2001/02 19