Fondamenti Teorici e Programmazione Modulo A Elementi di Programmazione Claudio Gallicchio, Ph.D.
Array 2
Dati Strutturati I tipi di dati visti finora sono numeri (interi o razionali) booleani (valori di verita') stringhe (sequenze di caratteri) Spesso e' necessario manipolare dati piu' complessi, che presentano una struttura Dati Strutturati 3
Array Gli array rappresentano un tipo di dato composto, formato da una sequenza di valori Ogni valore e' detto elemento dell'array Ad ogni valore e' associato un indice (numero d'ordine) Il numero di elementi in un array e' detto lunghezza (o dimensione) dell'array In JS gli array sono dinamici, cioe' possono avere lunghezza variabile Nota: In JS i valori che compongono un array possono essere omogenei (stesso tipo) o disomogenei (tipi diversi). Noi ci limitiamo al caso di array omogenei 4
Dichiarazione e inizializzazione La sintassi della dichiarazione di un array prevede alcune alternative Dichiarazione di un array vuoto alternativa 1 var nome_array = []; alternativa 2 var nome_array = new Array(); 5
Dichiarazione e Inizializzazione Dichiarazione di un array + inizializzazione degli elementi ad undefined var nome_array = new Array(lunghezza); Ad esempio var lunghezza = 7; var nome_array = new Array(lunghezza); writeln(nome_array); dichiara un array di lunghezza 7 inizializza ad undefined tutti i suoi elementi 6
Dichiarazione e Inizializzazione Dichiarazione di un array + inizializzazione degli elementi var nome_array = [espressione1, espressione2,..., espressionek]; Ad esempio var vettore = [1, -2, 3, 45]; writeln(vettore); dichiara un array di lunghezza 4 inizializza i suoi elementi a specifici valori indicati tra [ ] e separati da, 7
Dichiarazione e Inizializzazione Dichiarazione di un array + inizializzazione degli elementi (ver. 2) var nome_array = new Array(espressione1, espressione2,..., espressionek); Ad esempio var vettore = new Array(1, -2, 3, 45); writeln(vettore); dichiara un array di lunghezza 4 inizializza i suoi elementi a specifici valori indicati tra ( ) e separati da, 8
Accesso agli elementi di un array Ogni elemento di un array e' accessibile usando l'identificatore dell'array e l'indice dell'elemento es. nome_array[indice] L'indice puo' essere anche il risultato di un'espressione es. nome_array[espressione] L'indice deve essere un valore numerico intero, non negativo Gli array sono indicizzati a partire da 0 es.: gli indici di un array di 6 elementi variano da 0 (primo elemento) a 5 (ultimo elemento) Ricordare: vet[i] indica l'elemento dell'array vet di indice i 9
Rappresentazione grafica Supponiamo di aver dichiarato var vettore = new Array(7); possiamo rappresentare il vettore in forma tabellare Indice Elemento Variabile 0 undefined vettore[0] 1 undefined vettore[1] 2 undefined vettore[2] 3 undefined vettore[3] 4 undefined vettore[4] 5 undefined vettore[5] 6 undefined vettore[6] 10
Modifica di un array Gli elementi di un array possono essere modificati usando il comando di assegnamento ( = ) A sinistra dell'uguale si specifica l'espressione che denota l'elemento dell'array, a destra il suo nuovo valore var vettore = new Array(7); vettore[0] = 1; L'indice puo' essere una qualsiasi espressione che abbia un valore intero non negativo var i = Math.round(4.1); vettore[i] = Math.log(1); 11
Esempi di istruzioni che coinvolgono array Supponiamo di aver dichiarato il seguente array var vet = new Array(6); Indice Elemento Variabile ora eseguiamo le seguenti istruzioni e vediamo come cambia il contenuto dell'array vet[0] = 15; vet[1] = vet[0] + 4; write(vet[0]+vet[1]); 0 undefined vet[0] 1 undefined vet[1] 2 undefined vet[2] 3 undefined vet[3] 4 undefined vet [4] 5 undefined vet [5] 12
Esempi di istruzioni che coinvolgono array Dopo l'esecuzione di vet[0] = 15; Indice Elemento Variabile 0 15 vet[0] 1 undefined vet[1] 2 undefined vet[2] 3 undefined vet[3] 4 undefined vet [4] 5 undefined vet [5] 13
Esempi di istruzioni che coinvolgono array Dopo l'esecuzione di vet[1] = vet[0] + 4; Indice Elemento Variabile 0 15 vet[0] 1 19 vet[1] 2 undefined vet[2] 3 undefined vet[3] 4 undefined vet [4] 5 undefined vet [5] 14
Lo stato con gli array Quando si usano array, lo stato viene esteso. E' necessario considerare: l'ambiente che rappresenta le variabili come insieme di coppie lo heap in cui sono memorizzati gli array Le variabili che hanno come valore un array assumono nell'ambiente un valore speciale detto reference il reference e' un indirizzo di memoria che individua l'area dello heap in cui e' memorizzato l'array 15
Lo stato con gli array: reference e heap Lo heap in cui e' memorizzato l'array e' costituito da piu' locazioni di memoria (illustrato come nelle precedenti tabelle) Il reference e' indicato graficamente come una freccia (che punta allo heap), oppure con refi dal momento che l'indirizzo effettivo di memoria e' un dettaglio che dipende dal gestore della memoria (non ci interessa) 16
Esempio di stato var vet1 = new Array(6); Stato risultante: {(vet1, )} 0 undefined 1 undefined 2 undefined 3 undefined 4 undefined 5 undefined 17
Esempio di stato var vet1 = new Array(6); var vet2 = new Array(6); Stato risultante: {(vet1, ), (vet2, )} 0 undefined 1 undefined 2 undefined 3 undefined 4 undefined 5 undefined 0 undefined 1 undefined 2 undefined 3 undefined 4 undefined 5 undefined 18
Esempio di stato var vet1 = new Array(6); var vet2 = new Array(6); var a = 0; Stato risultante: {(vet1, ), (vet2, ), (a, 0)} 0 undefined 1 undefined 2 undefined 3 undefined 4 undefined 5 undefined 0 undefined 1 undefined 2 undefined 3 undefined 4 undefined 5 undefined 19
Esempio di stato var vet1 = new Array(6); var vet2 = new Array(6); var a = 0; vet1[0] = 4; Stato risultante: {(vet1, ), (vet2, ), (a, 0)} 0 4 1 undefined 2 undefined 3 undefined 4 undefined 5 undefined 0 undefined 1 undefined 2 undefined 3 undefined 4 undefined 5 undefined 20
Esempio di stato Stato risultante: {(vet1, ), (vet2, ), (a, 0)} var vet1 = new Array(6); var vet2 = new Array(6); var a = 0; vet1[0] = 4; vet1[1] = a; vet2[1]=vet1[1]+2; 0 4 1 0 2 undefined 3 undefined 4 undefined 5 undefined 0 undefined 1 2 2 undefined 3 undefined 4 undefined 5 undefined 21
Esempio di stato - Attenzione Stato risultante: {(vet1, ), (vet2, ), (a, 0)} var vet1 = new Array(6); var vet2 = new Array(6); var a = 0; vet1[0] = 4; vet1[1] = a; vet2[1]=vet1[1]+2; vet2 = vet1; 0 4 1 0 2 undefined 3 undefined 4 undefined 5 undefined 0 undefined 1 2 2 undefined 3 undefined 4 undefined 5 undefined vet1 e vet2 condividono lo stesso array cioe' hanno lo stesso reference nell ambiente l'area di memoria puntata dal vecchio reference di vet2 non e' piu' accessibile 22
Esempio di stato - Attenzione Stato risultante: {(vet1, ), (vet2, ), (a, 0)} var vet1 = new Array(6); var vet2 = new Array(6); var a = 0; vet1[0] = 4; vet1[1] = a; vet2[1]=vet1[1]+2; vet2 = vet1; vet1[2]=vet2[1]; 0 4 1 0 2 0 3 undefined 4 undefined 5 undefined 0 undefined 1 2 2 undefined 3 undefined 4 undefined 5 undefined la modifica a vet2 modifica anche vet2, dal momento che hanno lo stesso reference nell'ambiente 23
Osservazioni sugli array Anche l'operatore di uguaglianza opera sugli array: due variabili array se condividono la stessa struttura esercizio: valutare (vet1==vet2) prima e dopo l'istruzione vet2 = vet1; Gli operatori di confronto (<, >) non sono definiti su array attenzione: non viene generato errore, ma sempre false! Nell'ambiente EasyJS le funzioni write e writeln funzionano anche su array stampano gli elementi dell'array separati da virgole 24
Manipolazione di array La manipolazione di array avviene spesso tramite cicli, e in particolare (di solito) con l'istruzione iterativa for L'indice del ciclo varia da 0 a lunghezza-1 viene usato per scandire tutto l'array e per accedere a ciascun elemento dell'array Esempio: lettura e stampa di un vettore var lunghezza = readnum(); var i; var vet = new Array(lunghezza); for (i = 0; i < lunghezza; i++) vet[i] = readnum(); for (i = 0; i < lunghezza; i++) writeln("elemento di indice " + i + " " + vet[i]); 25
Array dinamici In JS gli array sono strutture dinamiche: il numero degli elementi puo' variare durante l'esecuzione del programma Per aggiungere un elemento ad array e' possibile assegnare un valore ad un elemento di indice successivo all'ultimo attualmente esistente Esempio: var L = 5, i = 0; var vet = new Array(L); //vet ha lunghezza 5 //gli elementi del vettore vengono riempiti con //le potenze di 2 for (i = 0;i < L; i++) vet[i] = Math.pow(2,i); vet[l] = Math.pow(2,L); //<--- vet ora ha lunghezza 6 26
Array dinamici Esempio var L = 5, i = 0; var vet = new Array(L); //vet ha lunghezza 5 //gli elementi del vettore vengono riempiti con //le potenze di 2 for (i = 0;i < L; i++) vet[i] = Math.pow(2,i); vet[l] = Math.pow(2,L); //<--- vet ora ha lunghezza 6 vet[l+2] = -1; //aggiunge due elementi 0 1 1 2 2 4 3 8 4 16 5 32 6 undefined 7-1 27
Lunghezza di un array In JS la lunghezza di un array e' una proprieta' dell'array Per conoscere la lunghezza di un array di nome occorre accedere alla sua proprieta' length Sintassi: nome_array.length Attenzione: la lunghezza dell'array e' uguale al massimo indice + 1 var L = 5, i = 0; var vet = new Array(L); writeln(vet.length); //stampa: 5 for (i = 0;i < vet.length; i++) //usa vet.length vet[i] = Math.pow(2,i); vet[vet.length] = Math.pow(2,L); //<--- vet ora ha lunghezza 6 writeln(vet.length); //stampa: 6 vet[vet.length+1] = -1; //aggiunge due elementi writeln(vet.length); //stampa: 8 28
Esempio Calcolo della somma degli elementi in un vettore var a = new Array(10); var i, somma = 0; // qui le istruzioni per riempire l'array //... //... // somma degli elementi nell'array: for (i = 0; i < a.length; i++) somma += a[i]; //stampiamo la somma: writeln(somma); 29
Esempio Calcolo del massimo tra gli elmenti (numerici) di un vettore var a = new Array(10); var i, max; // qui le istruzioni per riempire l'array //... //... // calcolo il massimo max = -Infinity; for (i = 0; i < a.length; i++) if (a[i]>max) max = a[i]; //stampiamo il massimo writeln(max); 30
Esempio Ricerca di un elemento con valore v in un array di lunghezza L Supponiamo che l'array non sia ordinato Calcolare true se l'elemento viene trovato, false altrimenti var a = new Array(10); var i, trovato = false; var v = readnum(); // elemento da cercare // qui le istruzioni per riempire l'array //... for(i = 0;i<a.length;i++) if (a[i] == v) trovato = true; //stampiamo il risultato if (trovato) writeln('trovato!'); else writeln('non trovato!'); 31
Esempio alternativa piu' efficiente Ricerca di un elemento con valore v in un array di lunghezza L, supponiamo che l'array non sia ordinato Se l'elemento viene trovato, stampare anche l'indice corrispondente nell'array Usiamo un' iterazione indeterminata var a = new Array(10); var i = 0, trovato = false; var v = readnum(); // elemento da cercare // qui le istruzioni per riempire l'array //... while (i<a.length &&!trovato) if (a[i] == v) trovato = true; else i++; //stampiamo il risultato if (trovato) writeln('trovato! indice = ' + i); else writeln('non trovato!'); 32
Esempio Shift a sinistra degli elementi di un vettore Occorre spostare di una posizione a sinistra tutti gli elementi del vettore. Es. con array di lunghezza 5 0 1 2 3 4 1 2 3 4 5 2 2 3 4 5 vet[0] = vet[1] var vet = new Array(5); //... for(i = 0; i<vet.length-1; i++) vet[i] = vet[i+1]; 2 3 3 4 5 2 3 4 4 5 2 3 4 5 5 vet[1] = vet[2] vet[2] = vet[3] vet[3] = vet[4] 33
Esempio Shift circolare a sinistra degli elementi di un vettore E' come uno shift a sinistra, ma l'elemento che esce dalla prima posizione rientra nell'ultima posizione 0 1 2 3 4 1 2 3 4 5 2 3 4 5 1 var vet = new Array(5); //... var c = vet[0]; for(i = 0; i<vet.length-1; i++) vet[i] = vet[i+1]; vet[vet.length-1] = c; 34
Esercizio Scrivere il codice JS per implementare lo shift e lo shift circolare a destra 35
Esempio Scrivere un programma per leggere N interi. Successivamente, leggere un intero y e stampare i valori maggiori di y precedentemente letti var N = readnum(); var vet = new Array(N); var y; var i; // leggo gli N valori for (i=0;i<n;i++) vet[i] = readnum(); // leggo y y = readnum(); // stampo i numeri > y for (i = 0; i<n; i++) if (vet[i]>y) writeln(vet[i]); 36