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 Code (queues) Liste Pile (stacks) ecc Laboratorio di Informatica 4. Array e strutture in C++ Corso di Laurea in Ingegneria Elettronica e Telecomunicazioni A.A. 2013-2014 2° Semestre Prof. Giovanni Pascoschi Laboratorio di Informatica – A.A. 2013-2014 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) (non in questo corso) 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] int voti[100]; double temperature[20]; Laboratorio di Informatica – A.A. 2013-2014 2 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. a cura di Pascoschi Giovanni ..... a cura di Pascoschi Giovanni 3 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 4 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]; Laboratorio di Informatica – A.A. 2013-2014 oppure int temp[ ] = {-5, -1, 3, 12, 15, 21 }; a cura di Pascoschi Giovanni 5 Accesso agli elementi di un Array Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 6 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 (int 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]; Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 7 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 8 Esempio 1 (algoritmo di massimo con gli array) Passaggio di array come parametri #include <iostream> using namespace std; Gli array possono essere usati come parametri di una funzione Gli array sono sempre passati per referenza (riferimento) 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; } Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni Esempio: Laboratorio di Informatica – A.A. 2013-2014 9 float media( int a [ ], int num) // definizione della funzione media ( temp, numero); // chiamata della funzione Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 10 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) 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 // dichiarazione prototipo N.B.: bisogna fornire la dimensione dell’array alla funzione perchè altrimenti non è nota 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; } float media( int [ ], int); Ogni modifica degli elementi dell’array parametro formale all’interno della funzione rappresenta, in effetti, una modifica agli elementi dell’array parametro attuale 11 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 12 Come avere un array come tipo restituito da una funzione? Elementi di un array come parametro Non è possibile usare un array come tipo restituito da una funzione: float[ ] funzione(....) Gli elementi di un array possono essere passati come parametro sia per valore che per riferimento come delle semplici variabili: // errore: non è possibile p.e.: 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 (non in questo corso) nel main swap( temp[i], temp[j] ); Definizione della funzione swap(int& a, int& b) Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 13 Array di caratteri Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni Array di caratteri la stringa è un array di caratteri con il terminatore ‘\0’ (carattere nullo) la manipolazione delle stringhe si puo’ realizzare manipolando array di char A differenza degli altri tipi di array è possibile stampare ed acquisire un array di caratteri globalmente (stringa): Esempi equivalenti: char citta[7] = “Milano”; cout<< citta; char citta = { ‘M’, ‘i’, ‘l’, ‘a’, ‘n’, ‘o’ }; char citta[ ] = { ‘M’, ‘i’, ‘l’, ‘a’, ‘n’, ‘o’ }; char citta[7] = “Milano”; Laboratorio di Informatica – A.A. 2013-2014 14 oppure cin>>nome; a cura di Pascoschi Giovanni 15 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 16 Array di caratteri e stringhe (differenza) Array di caratteri e stringhe (differenza) Gli oggetti della classe string possono essere considerati come array di caratteri di dimensione grande a piacere Ad esempio per copiare una stringa: I singoli caratteri possono essere modificati come gli elementi di un array di tipo char Esempio string citta = “Roma”; citta[1] = ‘i’; cout<<citta; string citta1, citta2; citta1 = citta2; // oggetto della classe string char citta1[10], citta2[10]; strcpy(citta1, citta2); // array di caratteri 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 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 17 Array multidimensionali 18 Per accedere all’elemento che si trova nella riga i e nella colonna j si utilizza la seguente notazione: Sintassi : tipo nomearray[dim1][dim2].....[dimn]; mat[i][j] Esempio: Gli array a 2 dimensioni si chiamano matrici cout<< mat[2][3]; Esempio: a cura di Pascoschi Giovanni // stampa l’elemento della matrice di coordinate 2 e 3 gli indici di riga e colonna partono entrambi dal valore 0 // matrice di 10 righe e 5 colonne Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni Matrici E’ possibile dichiarare array con piu’ dimensioni float mat[10][5]; Laboratorio di Informatica – A.A. 2013-2014 19 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 20 Memorizzazione di Matrici Inizializzazione di Matrici Gli array multidimensionali sono memorizzati per righe in locazioni contigue j 1 int mat[3][3]= { {1,0,0}, {0,1,0}, {0,0,1} }; mat[0][0] 2 3 4 0 ...... mat[0][4] j riga 0 0 Gli array multidimensionali possono essere inizializzati con una lista di valori di inizializzazione racchiusi tra parentesi graffe: Memoria 0 1 2 0 1 0 0 1 0 1 0 2 0 0 1 1 mat[1][0] 3 ....... 4 mat[1][4] 5 riga 1 i 2 i ...... 6 7 8 9 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 21 Esempio con matrici Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 22 Array multidimensionali come parametri Memorizzazione di una tavola pitagorica Nel caso di passaggio di array multidimensionali nella dichiarazione bisogna specificare: tutte le dimensioni ..................... 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); ................... Laboratorio di Informatica – A.A. 2013-2014 oppure tutte le dimensioni dalla seconda in poi (il compilatore ha bisogno di conoscere queste informazioni per poter accedere agli elementi nella memoria) a cura di Pascoschi Giovanni 23 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 24 Array multidimensionali come parametri (esempio 1) Array multidimensionali come parametri (esempio 2) void stampa(int mat[ROW][COL]) { void stampa(int mat[ ][COL], int n) { int i, j; for(i=0; i<ROW; i++) for(j=0; j<COL; j++) cout << mat[ i ] [ j ] << endl; } int i, j; for(i=0; i<n; i++) for(j=0; j<COL; j++) cout << mat[ i ] [ j ] << endl; } Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 25 Algoritmi fondamentali sugli array – Ricerca sequenziale 26 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 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 bool ricerca(int serie[ ], int n, int find) { bool trovato = false; int i = 0; while(i<n && !trovato) { if(serie[i] == find) trovato = true; i++; } return trovato; } a cura di Pascoschi Giovanni a cura di Pascoschi Giovanni Algoritmi fondamentali sugli array – Ricerca binaria(dicotomica) 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 Laboratorio di Informatica – A.A. 2013-2014 Laboratorio di Informatica – A.A. 2013-2014 27 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 28 Algoritmi fondamentali sugli array – Ricerca binaria (dicotomica) Algoritmi fondamentali sugli array – Ordinamento bool ricerca(int serie[ ], int n, int find) { 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] 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; } Esistono diversi algoritmi di ordinamento (Bubblesort, Insertion sort, Quicksort, Mergesort, Heapsort, ecc) return trovato; } Laboratorio di Informatica – A.A. 2013-2014 29 a cura di Pascoschi Giovanni Algoritmo di Ordinamento Bubblesort a cura di Pascoschi Giovanni 30 Algoritmo di Ordinamento Bubblesort : esempio 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 Laboratorio di Informatica – A.A. 2013-2014 non sono in ordine p.e. 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 Ripetere fintanto che si effettua almeno uno scambio (al massimo n ripetizioni) Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 31 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 32 Ordinamento Bubblesort Strutture di dati void bubblesort(int serie[ ], int n) { 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 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); sintassi struct nome_struttura { tipo1 nome_variabile1; ......... tipon nome_variabilen; } La struttura definisce un nuovo tipo di dato } Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 33 Strutture di dati a cura di Pascoschi Giovanni 34 Strutture di dati 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 Una volta definito un tipo dati struttura, essa si comporta come un qualsiasi altro tipo di dati. Si puo’ ad esempio: 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) esempio: cd.prezzo=10; cout<<cd.titolo; cd.copie++; Laboratorio di Informatica – A.A. 2013-2014 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 35 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 36 Esempi strutture di dati Tabelle di dati La tabella di dati è un array di strutture daticd cd1 = {“Toccata e fuga”, “Bach”, 30, sinfonia }; //uguaglianza tra strutture daticd cd2 = cd1; struct giorno { int gg; int mm; int aa; }; void stampa_cd(daticd x) { // passaggio per valore cout<<“x.autore<<x.titolo<<x.prezzo<<x.genere<<endl; } void prezzo_scontato(daticd& x) { x.prezzo=x.prezzo * 80/100; } Laboratorio di Informatica – A.A. 2013-2014 struct daticd { string titolo; string autore; float prezzo; string genere; struct giorno giorno_vendita; }; struct daticd CD[100]; // tabella costituita da 100 CD // passaggio per referenza a cura di Pascoschi Giovanni 37 Istruzione typedef Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 38 a cura di Pascoschi Giovanni 40 Riepilogo della lezione per poter descrivere in maniera piu’ concisa un tipo struttura si puo’ usare la parola chiave typedef Funzioni in C++ struct giorno { int gg; int mm; int aa; }; 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 Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 39 Array in C++ Array come parametro nelle funzioni Array di caratteri Matrici (array multidimensionali) Algoritmi fondamentali sugli array Strutture di dati Tabelle di dati Laboratorio di Informatica – A.A. 2013-2014 Fine della lezione Domande? Laboratorio di Informatica – A.A. 2013-2014 a cura di Pascoschi Giovanni 41