Lezione 3 Tipi di Dato Derivati Tipi di Dato Derivati Laboratorio di Algoritmi e Strutture Dati 2001-02 ü Un tipo di dato derivato è ottenuto a Tipi di Dato Derivati partire da tipi di dato predefiniti attraverso gli operatori *, &, [] definendo enumerazioni ® definendo struct ® Lezione 3 ® ü I tipi di dato derivati non sono tipi di dati nuovi, ma semplice composizione di tipi di dati esistenti Indicizzazione di un Array ü Un array è un insieme di oggetti dello stesso tipo ü Le posizioni degli oggetti in un array si contano da 0 ü Il compilatore non effettua nessun controllo sulla ü La dimensione dell’array può essere qualsiasi espressione costante ® non può essere variabile 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 2 3 Array di char ü L’array è inizializzato dando la lista dei valori ü E’ possibile inizializzare un array di char 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 Laboratorio di Algoritmi e Strutture Dati 2001-02 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 Laboratorio di Algoritmi e Strutture Dati 2001-02 Array Laboratorio di Algoritmi e Strutture Dati 2001-02 1 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 4 Laboratorio di Algoritmi e Strutture Dati 2001/02 5 1 Array Multidimensionali ü Non è possibile inizializzare o assegnare un array ad un ü Si definisce un array multidimensionale specificando 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 Laboratorio di Algoritmi e Strutture Dati 2001-02 Lezione 3 Tipi di Dato Derivati 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] 6 Inizializzazione di Array Multidimensionali 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}}; ü Per accedere ad un elemento di un array Laboratorio di Algoritmi e Strutture Dati 2001-02 ® ogni Accesso a Array Multidimensionali Laboratorio di Algoritmi e Strutture Dati 2001-02 ü Un array bidimensionale è un array di array 7 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 ®ia[3] è un array 9 Tipo di un Array ü Alla definizione di un array il compilatore alloca ü Il tipo di un array è puntatore al tipo degli 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 char* indir. Laboratorio di Algoritmi e Strutture Dati 2001-02 Relazione tra Array e Puntatori Laboratorio di Algoritmi e Strutture Dati 2001-02 8 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 */ 10 Laboratorio di Algoritmi e Strutture Dati 2001/02 11 2 Lezione 3 Tipi di Dato Derivati 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; ü 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 // ERRORE 12 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 Definizione di oggetti vector vector<T> a; /* Definisce un vettore di tipo T il cui Laboratorio di Algoritmi e Strutture Dati 2001-02 ü La classe vector della libreria standard è una valida 13 Laboratorio di Algoritmi e Strutture Dati 2001-02 Il Contenitore vector identificatore è a e la cui dimensione è 0 */ // equivale a T a[5]; // Definisce un vettore di tipo T di 5 elementi vector<T> a(5); // equivale a T a[] = {4, 4, 4, 4, 4} /* Definisce un vettore di tipo T di 5 elementi inizializzati con 4 */ vector<T> a(5, 4); 15 ü L'accesso al vector può essere fatto tramite ü E' possibile accedere agli elementi del vector in 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 Accesso a elementi di vector stile STL Laboratorio di Algoritmi e Strutture Dati 2001-02 14 ® Laboratorio di Algoritmi e Strutture Dati 2001-02 ü L’identificatore dell’array si comporta Differenze tra Array e Puntatori Laboratorio di Algoritmi e Strutture Dati 2001-02 Tipo di un Array 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; 16 Laboratorio di Algoritmi e Strutture Dati 2001/02 17 3 Lezione 3 Tipi di Dato Derivati ® 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 ü per utilizzare i metodi della classe vector si usa l'operatore di selezione vector<int> v; v.metodo(); 18 19 Algoritmi su vector ü un oggetto vector può essere allungato dinamicamente ü La libreria standard fornisce una serie di algoritmi 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 ® 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(), adjacent_differences() 20 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; } 21 Stringhe Laboratorio di Algoritmi e Strutture Dati 2001-02 Esempio uso vector #include <vector> #include <algorithm> #include <iostream> Laboratorio di Algoritmi e Strutture Dati 2001-02 ® 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 Laboratorio di Algoritmi e Strutture Dati 2001-02 puntatore ü 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’) 22 Laboratorio di Algoritmi e Strutture Dati 2001/02 Laboratorio di Algoritmi e Strutture Dati 2001-02 ü L'iteratore è una classe che implementa l'astrazione del Alcuni metodi della classe vector Laboratorio di Algoritmi e Strutture Dati 2001-02 Iteratori 23 4 Lezione 3 Tipi di Dato Derivati Operazioni sulle 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” ü La libreria standard del C fornisce funzioni per Laboratorio di Algoritmi e Strutture Dati 2001-02 Esempio Stringhe 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 25 Esempio uso di string ü La libreria standard fornisce una nuova ü Calcolare la lunghezza della stringa “ciao mondo\n” 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 Laboratorio di Algoritmi e Strutture Dati 2001-02 24 #include <iostream> #include <string> string st = “ciao mondo\n”; int main() { int lung = st.size(); cout << “lunghezza di “ << st << “ = “ << lung; return 0; } 26 Enumerazioni ü Un’enumerazione è un insieme di costanti simboliche Laboratorio di Algoritmi e Strutture Dati 2001-02 Laboratorio di Algoritmi e Strutture Dati 2001-02 Alcuni metodi della classe string 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 27 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 28 Laboratorio di Algoritmi e Strutture Dati 2001/02 29 5 Lezione 3 Tipi di Dato Derivati Tipo bool ü 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 ü Una variabile di tipo bool può assumere come valori solo i valori true e false bool trovato = false; 30 Struct Classi 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 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 (->) 31 ü 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 ® string e vector<T> sono classi 32 ü L’operatore typedef consente di assegnare un Laboratorio di Algoritmi e Strutture Dati 2001-02 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; }; 33 Typedef Laboratorio di Algoritmi e Strutture Dati 2001-02 Esempio di classe String Laboratorio di Algoritmi e Strutture Dati 2001-02 un’enumerazione colore vernice = giallo; //vernice può assumere solo i valori giallo, rosso, verde e bianco Laboratorio di Algoritmi e Strutture Dati 2001-02 ü E’ possibile definire una variabile del tipo definito da Laboratorio di Algoritmi e Strutture Dati 2001-02 Enumerazioni 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 34 Laboratorio di Algoritmi e Strutture Dati 2001/02 35 6 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 7