
// Tipi di dato complessi

public class Esempio17 {
    
	public static void main(String[] args) {
		
		// Un altro modo di rappresentare l'informazione: uso un array di Persona
		// dove Persona è un tipo che definisco a parte nel file "Persona.java"
		
		int persone = 10;  // numero di persone
		Persona[] rubrica; // i miei dati
		// Alloco memoria
		rubrica = new Persona[persone];
		// Inizializzo
		rubrica[0] = new Persona(); // creo una coppia nome-tel
		rubrica[0].nome     = "Mario";
		rubrica[0].telefono = "555-231";
		rubrica[1] = new Persona();
		rubrica[1].nome     = "Giuseppe";
		rubrica[1].telefono = "555-232";
		rubrica[2] = new Persona();
		rubrica[2].nome     = "Asdrubale";
		rubrica[2].telefono = "555-624";
		// ... eccetera
		
		// Si noti che le coppie di sopra sono allocate con la "new" come
		// per gli array. Anche questa è una forma di alocazione dinamica.
		// Lo spazio per le coppie allocate sopra viene allocato come
		// per gli array. 
		//
		// Analogamente a quello che avviene con gli array, la semantica
		// dell'espressione rubrica[1] non è un coppia-persona, ma è un *riferimento*
		// alla memoria appena allocata. Lo osserveremo in pratica poco sotto.
		
		// Stampo la rubrica (o almeno la parte inserita sopra)
		int i;
		for (i = 0 ; i<3 ; i++) {
			Persona p = rubrica[i];
			System.out.println("Nome: " + p.nome + "   Telefono: " + p.telefono);
		}
		
		// Modifico la rubrica aggiungendo un prefisso "0039-" davanti ai numeri.
		for (i = 0 ; i<3 ; i++) {
			Persona p = rubrica[i];
			// Ora p contiene lo stesso riferimento a Persona di rubrica[i].
			p.telefono = "0039-" + p.telefono;
			// Questo di sopra modifica effettivamente la Persona nell'array
			// rubrica.
			//
			// Per capire csa sta succedendo, consideriamo il seguente:
			//    x=5;
			//    y=x;
			//    y=7;
			// L'ultimo assegnamento non modifica x (ovviamente!).
			// Analogamente, si consideri:
			//    rubrica[4] = ...;
			//    p = rubrica[4];
			//    p = ...;
			// Anche qui l'ultimo assegnamento non modifica rubrica[4].
			// Tuttavia:
			//    rubrica[4] = new Persona();
			//    rubrica[4].nome = "Gigi";
			//    p = rubrica[4];
			//    p.nome = "Luca";
			// Qui, l'ultimo assegnamento *cambia* il nome di rubrica[4].
			//
			// Si noti che il valore di rubrica[4] è invariato, nel senso che
			// continua a riferirsi alla stessa coppia allocata in memoria.
			// Tuttavia, è la coppia che si trova in memoria a quel riferimento
			// ad essere cambiata.
			// 
			// Il fatto che p e rubrica[4] si riferiscano alle stessa celle
			// di memoria è una forma di aliasing, simile a:
			//    int[] a;
			//    int[] b;
			//    a = new int[10];
			//    a[1] = 5;
			//    b = a;
			//    b[1] = 7; // sovrascrive a[1], visto che il riferimento è lo stesso
		}

		// Ri-stampo la rubrica (o almeno la parte inserita sopra)
		// Nota: visto che sto usando la stessa stampa due volte,
		// sarebbe meglio definirsi una procedura da chiamare due volte
		// piuttosto che fare copia&incolla del codice!
		for (i = 0 ; i<3 ; i++) {
			Persona p = rubrica[i];
			System.out.println("Nome: " + p.nome + "   Telefono: " + p.telefono);
		}

		
	}

}
