Strutture Dati in C++ Le strutture dati sono entità che permettono di memorizzare dati in modo organizzato e funzionale a particolari esigenze Strutture Dati tipiche in C++ ¾Array ¾Matrici ¾Strutture ¾Classi ¾Vector ¾Code (queues) ¾Liste ¾Pile (stacks) ¾ecc Fondamenti di Informatica II 7. Array e Strutture in C++ Corso di Laurea in Ingegneria Informatica A.A. 2008-2009 2° Semestre – Corso (A-M) Prof. Giovanni Pascoschi 2 Array (vettori) Le variabili di un array (elementi) vengono identificate da un nome a cui va aggiunto un indice tra parentesi quadre (che parte da 0) In C++ ci sono due tipi di array ¾array (come nel C) ¾vector (classe Standard Template Library) (nel secondo modulo) Memoria I vari elementi sono memorizzati in locazioni di memoria successive voti[0] 8 voti[1] 4 voti[2] 3 Il numero di elementi di un array è fisso sintassi il numero di byte che l’array occupa in memoria = numero di elementi * numero di byte per ciascun elemento tipo nomearray[espressione costante] 3 a cura di Pascoschi Giovanni Array (vettori) Un array è un insieme finito di N variabili dello stesso tipo, ognuno identificata da un indice compreso tra 0 e N-1 p.e. Fondamenti di Informatica II – A.A. 2008-2009 ..... int voti[100]; double temperature[20]; Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 4 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Elementi di un Array Dichiarazione di un Array Gli elementi di un array possono essere usati come una qualsiasi variabile del tipo dell’array E’ possibile inizializzare i valori di un array in fase di dichiarazione Esempi: Esempi: int temp[6] = {-5, -1, 3, 12, 15, 21 }; voti[3] = 28; cout << voti[13]; cin >> voti[32]; voto_diff = voti[2] – voti[18]; 5 Fondamenti di Informatica II – A.A. 2008-2009 oppure int temp[ ] = {-5, -1, 3, 12, 15, 21 }; a cura di Pascoschi Giovanni 6 Accesso agli elementi di un Array Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Bound checking L’indice di un array puo’ essere una espressione costante intera o comunque una qualsiasi espressione intera Il linguaggio C++ non prevede nessun meccanismo di controllo che un indice di un array cada all’interno dell’intervallo [0,....,N-1] dove N è la dimensione dell’array (bound checking) Esempio: In teoria è possibile anche usare indici negativi for (i=0; i< 500; i++) { cin >> voti[i]; cout << voti[i]; } In questi casi di fuoriuscita dell’indice dall’intervallo si accede a celle di memoria che precedono o seguono l’area di memoria dov’è allocato l’array Æ si sporca l’area di memoria producendo in alcuni casi anche il crash del programma o comunque effetti indisiderati nell’elaborazione del programma Esempio: cout << voti[ -3]; 7 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 8 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Esempio 1 (algoritmo di massimo con gli array) #include <iostream> using namespace std; Gli array possono essere usati come parametri di una funzione int main () { int temp[100]; .......caricamento dei dati nell’array... int i, max; for(i=0; i<100; i++) { if(i == 0) max = temp[i]; else { if( temp[i] > max) max = temp[i]; } } cout << “Il valore piu’ grande è “ << max; return 0; } 9 Fondamenti di Informatica II – A.A. 2008-2009 Passaggio di array come parametri a cura di Pascoschi Giovanni Gli array sono sempre passati per referenza (riferimento) Esempio: float media( int [ ], int); // dichiarazione prototipo float media( int a [ ], int num) // definizione della funzione media ( temp, numero); // chiamata della funzione N.B.: bisogna fornire la dimensione dell’array alla funzione perchè altrimenti non è nota 10 Esempio di passaggio di un array in una funzione #include <iostream> using namespace std; float media(int [ ], int); // prototipo della funzione const int MAX = 100; float med; int main () { int temp[ MAX ]; int num; .......caricamento parziale dei dati nell’array... med = media( temp, num); ......... return 0; } 11 Fondamenti di Informatica II – A.A. 2008-2009 float media(int a[ ], int numero) { int somma = 0; for (int i=0; i<numero; i++) { somma += a[i]; } return somma/numero; } a cura di Pascoschi Giovanni Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Array come parametri Al momento della chiamata il nome del parametro formale passato per riferimento diventa un sinonimo (alias) del parametro attuale facente riferimento allo stesso array (non si crea un nuovo array ma un riferimento ad un array esistente) Ogni modifica degli elementi dell’array parametro formale all’interno della funzione rappresenta, in effetti, una modifica agli elementi dell’array parametro attuale 12 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Array come parametri Come avere un array come tipo restituito da una funzione? Se gli elementi della funzione non devono essere modificati si puo’ usare const nella specifica dei parametri formali Non è possibile usare un array come tipo restituito da una funzione: float[ ] funzione(....) float media(const int a[ ], int numero) { int somma = 0; for (int i=0; i<numero; i++) { somma += a[i]; } return somma/numero; } 13 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni // errore: non è possibile Soluzioni: passare un array per riferimento (dove passera’ l’insieme dei dati) restituire un puntatore ad un array (non locale) Ævedremo in seguito usare la classe vector (vedremo nel 2. modulo) 14 Elementi di un array come parametro Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Array di caratteri Gli elementi di un array possono essere passati come parametro sia per valore che per riferimento come delle semplici variabili: la stringa è un array di caratteri con il terminatore ‘\0’ (carattere nullo) la manipolazione delle stringhe si puo’ realizzare manipolando array di char p.e.: Esempi equivalenti: nel main swap( temp[i], temp[j] ); char citta = { ‘M’, ‘i’, ‘l’, ‘a’, ‘n’, ‘o’ }; char citta[ ] = { ‘M’, ‘i’, ‘l’, ‘a’, ‘n’, ‘o’ }; char citta[7] = “Milano”; Definizione della funzione swap(int& a, int& b) 15 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 16 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Array di caratteri Array di caratteri e stringhe (differenza) A differenza degli altri tipi di array è possibile stampare ed acquisire un array di caratteri globalmente (stringa): Gli oggetti della classe string possono essere considerati come array di caratteri di dimensione grande a piacere char citta[7] = “Milano”; cout<< citta; I singoli caratteri possono essere modificati come gli elementi di un array di tipo char oppure cin>>nome; Esempio string citta = “Roma”; citta[1] = ‘i’; cout<<citta; La classe string fornisce una rappresentazione piu’ astratta di una stringa ed è piu’ facile lavorare con oggetti della classe string che con array di caratteri 17 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 18 Array di caratteri e stringhe (differenza) Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Array multidimensionali Ad esempio per copiare una stringa: E’ possibile dichiarare array con piu’ dimensioni string citta1, citta2; citta1 = citta2; // oggetto della classe string Sintassi : tipo nomearray[dim1][dim2].....[dimn]; char citta1[10], citta2[10]; strcpy(citta1, citta2); // array di caratteri Gli array a 2 dimensioni si chiamano matrici Esempio: float mat[10][5]; 19 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 20 // matrice di 10 righe e 5 colonne Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Matrici Memorizzazione di Matrici Per accedere all’elemento che si trova nella riga i e nella colonna j si utilizza la seguente notazione: Gli array multidimensionali sono memorizzati per righe in locazioni contigue j mat[i][j] 1 mat[0][0] 2 3 ...... 4 0 mat[0][4] riga 0 0 Esempio: Memoria 1 // stampa l’elemento della matrice di coordinate 2 e 3 i gli indici di riga e colonna partono entrambi dal valore 0 2 mat[1][0] 3 ....... 4 mat[1][4] 5 ...... 6 7 8 9 21 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 22 Inizializzazione di Matrici Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Esempio con matrici Gli array multidimensionali possono essere inizializzati con una lista di valori di inizializzazione racchiusi tra parentesi graffe: Memorizzazione di una tavola pitagorica int mat[3][3]= { {1,0,0}, {0,1,0}, {0,0,1} }; ..................... const int ROW=10, COL=10; int mat[ROW][COL]; int i,j; for(i=0; i<ROW; i++) for(j=0; j<COL; j++) mat[ i ] [ j ] = (i+1) * (j+1); ................... j i 23 0 1 2 0 1 0 0 1 0 1 0 2 0 0 1 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 24 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni riga 1 cout<< mat[2][3]; Array multidimensionali come parametri Array multidimensionali come parametri (esempio 1) Nel caso di passaggio di array multidimensionali nella dichiarazione bisogna specificare: ¾tutte le dimensioni void stampa(int mat[ROW][COL]) { ¾oppure tutte le dimensioni dalla seconda in poi (il compilatore ha bisogno di conoscere queste informazioni per poter accedere agli elementi nella memoria) 25 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni int i, j; for(i=0; i<ROW; i++) for(j=0; j<COL; j++) cout << mat[ i ] [ j ] << endl; } 26 Array multidimensionali come parametri (esempio 2) Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Algoritmi fondamentali sugli array – Ricerca sequenziale Scrivere una funzione che dato in input un array di interi serie[ ] ed un numero find, restituisca vero o falso a seconda che il numero find sia presente o meno nell’array void stampa(int mat[ ][COL], int n) { bool ricerca(int serie[ ], int n, int find) { int i, j; for(i=0; i<n; i++) for(j=0; j<COL; j++) cout << mat[ i ] [ j ] << endl; } bool trovato = false; int i = 0; while(i<n && !trovato) { if(serie[i] == find) trovato = true; i++; } return trovato; } 27 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 28 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Algoritmi fondamentali sugli array – Ricerca binaria(dicotomica) Algoritmi fondamentali sugli array – Ricerca binaria (dicotomica) Scrivere una funzione che dato in input un array ordinato di interi serie[ ] ed un numero find, restituisca vero o falso a seconda che il numero find sia presente o meno nell’array bool ricerca(int serie[ ], int n, int find) { bool trovato = false; int sx = 0, dx = n-1, med = (sx + dx)/2; while(sx<=dx && !trovato) { if(serie[med] == find) trovato = true; else if (find<serie[med]) dx=med-1; else sx=med+1; med=(sx+dx)/2; } Supponiamo che l’array sia ordinato in senso crescente: serie[0]<=serie[1]<=.....serie[n-1] Passi dell’algoritmo 1.sx=0 , dx=n-1, med=(sx+dx)/2 2.si confronta l’elemento cercato find con l’elemento mediano serie[med] 3.se find=serie[med] il numero è presente 4.altrimenti, se il vettore ha almeno due elementi se find<serie[med] si ripete la ricerca nella prima metà del vettore (da serie[0] a serie[med-1] ¾ si aggiornano dx e med e si va al passo 2 se find>serie[med] si ripete la ricerca nella seconda metà del vettore (da serie[med+1] a serie[dx] ¾ si aggiornano sx e med e si va al passo 2 29 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni return trovato; } 30 Algoritmi fondamentali sugli array – Ordinamento Dato un array di elementi (interi, float, stringhe,...) serie[ ] ordinare gli elementi dell’array in ordine crescente o decrescente, ossia in maniera tale che: serie[0]<= serie[1]<= serie[2]<=.......<= serie[n-1] Esistono diversi algoritmi di ordinamento (Bubblesort, Insertion sort, Quicksort, Mergesort, Heapsort, ecc) Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Algoritmo di Ordinamento Bubblesort si scandisce la lista degli elementi confrontando coppie di elementi successivi: serie[0] con serie[1] serie[1] con serie[2] ....... serie[n-2] con serie[n-1] Per ogni coppia, se i due elementi serie[i]>serie[i+1] scambiare gli elementi non sono in ordine p.e. Ripetere fintanto che si effettua almeno uno scambio (al massimo n ripetizioni) 31 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 32 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Algoritmo di Ordinamento Bubblesort : esempio Ordinamento Bubblesort 6 6 6 6 25 2 2 2 2 25 4 4 4 4 25 25 45 45 45 32 32 32 32 45 passo 1 2 2 6 4 4 6 25 25 32 32 45 45 passo 2 2 4 6 25 32 45 passo 3 void bubblesort(int serie[ ], int n) { int i; bool swapped; do { swapped=false; for(i=0;i<n-1;i++) { if (serie[i]>serie[i+1]) { swap(serie[i],serie[i+1]); swapped=true; } } } while(swapped); } 33 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 34 Strutture di dati Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Strutture di dati Una struttura è un insieme finito di variabili (dette campi) non necessariamente dello stesso tipo, ognuna identificata con un nome l’insieme dei campi è denominato record Dopo aver definito una variabile struttura, si accede ai singoli campi mediante la notazione . (punto) i campi di una struttura possono essere usati come qualunque variabile dello stesso tipo sintassi struct nome_struttura { tipo1 nome_variabile1; ......... tipon nome_variabilen; } esempio: cd.prezzo=10; cout<<cd.titolo; cd.copie++; La struttura definisce un nuovo tipo di dato 35 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 36 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Strutture di dati 37 Esempi strutture di dati Una volta definito un tipo dati struttura, essa si comporta come un qualsiasi altro tipo di dati. Si puo’ ad esempio: daticd cd1 = {“Toccata e fuga”, “Bach”, 30, sinfonia }; daticd cd2 = cd1; //uguaglianza tra strutture ¾assegnare una variabile struttura ad un’altra ¾far si’ che una funzione restituisca una struttura alla funzione chiamante ¾passare strutture sia per valore che per referenza (riferimento) void stampa_cd(daticd x) { // passaggio per valore cout<<“x.autore<<x.titolo<<x.prezzo<<x.genere<<endl; } Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni void prezzo_scontato(daticd& x) { x.prezzo=x.prezzo * 80/100; } 38 Tabelle di dati 39 Fondamenti di Informatica II – A.A. 2008-2009 // passaggio per referenza a cura di Pascoschi Giovanni Istruzione typedef La tabella di dati è un array di strutture per poter descrivere in maniera piu’ concisa un tipo struttura si puo’ usare la parola chiave typedef struct giorno { int gg; int mm; int aa; } struct giorno { int gg; int mm; int aa; } struct daticd { string titolo; string autore; float prezzo; string genere; struct giorno giorno_vendita; } struct daticd CD[100]; // tabella costituita da 100 CD struct daticd { string titolo; string autore; float prezzo; string genere; struct giorno vendita; } typedef struct daticd cddata; //non definisce un nuovo tipo, ma un sinonimo!!!! cddata CD[100]; // tabella costituita da 100 CD Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni 40 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni Riepilogo della lezione Fine della lezione Funzioni in C++ Array in C++ Array come parametro nelle funzioni Array di caratteri Matrici (array multidimensionali) Algoritmi fondamentali sugli array Strutture di dati Tabelle di dati 41 Fondamenti di Informatica II – A.A. 2008-2009 Domande? a cura di Pascoschi Giovanni 42 Fondamenti di Informatica II – A.A. 2008-2009 a cura di Pascoschi Giovanni