Utente:LoStrangolatore/corsojava/lez03
Calcoli
modificaRiprendiamo ora l'esempio dei calcoli fatto nella scorsa lezione. Quelli non erano calcoli veri.
public class CalcoliVeri {
public static void main(String[] args) {
System.out.println("Un paio di calcoli veri:");
System.out.println();
System.out.print("Tre più cinque fa ");
System.out.println(3 + 5);
System.out.print("Cassa più forte fa ");
System.out.print("cassa" + "forte");
}
}
Salviamo sul file CalcoliVeri.java, avviamo il compilatore e la macchina virtuale.
Il programma esegue l'istruzione System.out.println(3 + 5);
in questo modo:
- Calcola il valore 3 + 5 e scopre che vale 8;
- richiama la versione di println che accetta un numero, passandogli il numero 8.
Quindi l'istruzione println(3 + 5) si comporta esattamente come l'istruzione println(8) con la differenza che il programma non saprà che si tratta del numero 8, finché non incontra l'operazione di addizione e la esegue.
Due righe dopo facciamo la stessa cosa con le stringhe. In Java l'operatore + applicato alle stringhe fa questo: prende in ingresso due stringhe e restituisce una nuova stringa che contiene tutti i caratteri della prima, seguiti dai caratteri della seconda. In questo caso il simbolo +
non ha significato di somma algebrica, ma di concatenazione tra stringhe. Si dice che l'operatore +
è overloaded perché ha un significato diverso a seconda del tipo dei suoi operandi.
Variabili
modificaTODO: Nel testo che segue, sostituire qualcos'altro al peso della torre di Pisa e dell'Empire State Building. Usare due numeri che siano minori di 40.000 circa, altrimenti il prodotto di n per se stesso diventa maggiore di Integer.MAX_VALUE (che è circa due miliardi), va in overflow, e così il programma restituisce un risultato errato quando viene eseguito. Un gruppo di studiosi ci commissiona un programma che generi determinate statistiche sulla torre di Pisa. In particolare, sapendo che il peso della torre è di 14.453 tonnellate, vogliono un programma che stampi a video
- la somma di tutti i numeri da uno a 14.453. (Un modo per risolverlo è usare la formula di Gauss: n * (n + 1) / 2. Basta sostituire n = 14.453, calcolare e il gioco è fatto.)
- TODO: mettere qualche altro punto
public class CalcoliScientifici {
public static void main(String[] args) {
...
System.out.println("La somma di tutti i numeri da 1 a 10000 è: " + (14.453 * (14.453 + 1) / 2));
}
}
Il programma funziona e ottiene un discreto successo presso la comunità scientifica, così un altro gruppo di studiosi ci chiede di modificarlo perché svolga gli stessi calcoli a partire dal peso dell'Empire State Building, che si stima essere di circa 275.000 tonnellate.
Dobbiamo modificare il programma con il nuovo valore, questo è certo. Ma il problema è che dobbiamo modificarlo tutto: dobbiamo sostituire tutte le occorrenze del vecchio peso con il nuovo valore, e dobbiamo stare attenti a farlo in ogni riga. Se dimentichiamo di una delle occorrenze, il programma calcolerà un risultato errato, e quel che è peggio non darà nessun errore mentre lo fa. Il gruppo di studiosi fonderà i suoi studi successivi su delle stime errate, e ciò farà cattiva pubblicità al nostro programma, ma soprattutto a noi.
Sarebbe bello se fosse possibile scrivere il valore una sola volta, e richiamarlo ogni volta che bisogna calcolare qualcosa.
Usiamo una variabile
modificaTODO: Mettere qui una versione del programma di prima, che faccia uso di una variabile int peso.
Questa versione del programma può essere modificata molto più facilmente: basta modificare una sola riga, quella che definisce la variabile peso.
Cos'è una variabile
modificaUna variabile è come una scatola che può contenere al massimo un valore. Tutti i valori ammessi per una certa variabile sono determinati dal tipo della variabile. In questo caso, la variabile può contenere solo numeri interi, perché tipo è int. In particolare, int definisce tutti gli interi compresi tra TODO: (valori minimo e massimo per il tipo int). Esistono altri tipi numerici; ad esempio, scrivendo long peso; facciamo sì che la variabile peso possa contenere alcuno dei numeri interi compresi tra TODO: (valori minimo e massimo per il tipo long).
Riassumendo, i cosiddetti tipi primitivi del Java sono i seguenti:
TODO: (tabella con tutti i tipi primitivi)
Cosa succede a tempo di esecuzione
modificaQuella che abbiamo usato si chiama variabile locale, perché "appartiene" al metodo. Quando la macchina virtuale esegue il metodo main, incontra l'istruzione int peso; e quindi riserva una parte della memoria RAM del computer per questa variabile. Nessun altro programma, e nessuna altra variabile del nostro programma CalcoliScientifici, può interferire con questa zona di memoria.
Quando il metodo main termina, la variabile non serve più, quindi la macchina virtuale "libera" la memoria RAM che aveva occupato, e la rende disponibile per altre variabili o strutture dati nel programma.
La quantità di memoria è decisa in base al tipo della variabile, ed è sufficiente a contenere tutti i valori possibili per quel tipo. Per esempio, la variabile peso occuperà in memoria almeno quattro byte, perché quattro byte sono il minimo che permette di rappresentare correttamente ognuno dei numeri del tipo int. In realtà, la quantità esatta potrebbe essere anche maggiore; per esempio potrebbe essere di otto byte, oppure di cinque o dieci, a seconda della configurazione che è più comoda per la macchina virtuale; nonostante ciò, la variabile conterrà sempre e solo interi minori di TODO: valore intero di Integer.MAX_VALUE, e valori superiori faranno andare la variabile in overflow. Insomma, a prescindere dalla VM e dalle impostazioni del sistema, ogni variabile di tipo int si comporta sempre esattamente come se occupasse quattro byte e non oltre, e un discorso analogo vale per gli altri tipi primitivi.
Le stringhe
modificaCi potrà essere utile anche il tipo che in Java realizza le stringhe: esso si chiama String. Ad esempio possiamo scrivere:
public class HelloWorldConVariabile {
public static void main(String[] args) {
String messaggio = "Hello, world!";
System.out.println(messaggio);
}
}
Compiliamo con javac, lanciamo la macchina virtuale, e osserviamo il risultato.
Esercizio: date le variabili String hello = "Hello"; e String world = "world"; sei in grado di usarle per scrivere sull'output il messaggio completo Hello, world!? Trovi una possibile soluzione in fondo alla pagina.
Regole
modificaPer convenzione, i nomi delle variabili usano la notazione "camel case" e la prima parola comincia sempre con la minuscola. I caratteri utilizzati più di frequente sono i caratteri alfanumerici e gli underscore. Quindi possiamo avere hello, var1, variabileNumeroDue, pesoDellaTorreDiPisa o _prova.
L'istruzione int var; dichiara la variabile, cioè dice al compilatore che legge il codice sorgente: all'interno del blocco corrente, da questo punto in poi, il simbolo var identifica una variabile di tipo int. La variabile "scompare" non appena il programma esce dal blocco corrente. TODO: Specificare meglio il concetto di scope della variabile.
L'istruzione var = 3; assegna il valore 3 alla variabile, cioè scrive questo numero nella memoria occupata dalla variabile. Si può assegnare ad una variabile un nuovo valore, e questo ha l'effetto di sovrascrivere quello precedente.
TODO: Non si può leggere una variabile senza prima averla dichiarata o averci scritto dentro un valore.
TODO: Ci si può costringere ad assegnare max un valore ad una variabile, dichiarandola final. Ciò torna utile, ad esempio, se si sta definendo una costante nel programma.
Soluzioni
modificaDi seguito sono proposte alcune possibili soluzioni agli esercizi che trovi nella lezione.
public class HelloWorldConDueVariabili {
public static void main(String[] args) {
String hello = "Hello";
String world = "world";
System.out.println(hello + ", " + world + "!");
}
}