Le variabili

I calcolatori elettronici consentono di memorizzare ed eleborare i dati.

Le variabili si usano per memorizzare dati.


La metafora della lavagna

La memoria è come una lavagna, in cui è possibile memorizzare dati.

Una variabile è un rettangolo in cui si può mettere un singolo dato.


Metafora del cassetto

Ogni variabile è un cassetto.

Invece di contenere calzini, maglioni, ecc. ogni cassetto contiene un dato.


Memoria di una calcolatrice/telefonino

In una "posizione" della memoria di un cellulare si può memorizzare un numero di telefono.

Quando serve, si possono vedere i numeri memorizzati, oppure usarli (per esempio, per chiamare).


Caratteristiche delle variabili

  1. in una variabile si può memorizzare un dato;
  2. si può leggere/usare il dato memorizzato in una variabile.

Tipo di dato:

var. intere
possono contenere solo numeri interi
var. reali
possono contenere numeri reali
var. stringa
possono contenere solo stringhe
(stringa = sequenza di caratteri)

Dichiarazione delle variabili

Nei telefonini o calcolatrici le memorie sono predisposte (si possono usare da subito).

In Java, le variabili vanno dichiarate.

La dichiarazione di variabile contiene:

tipo
intero, reale, stringa, ecc.
nome
quello che usiamo per memorizzare ed estrarre il valore memorizzato

Facile su un esempio.


Una variabile, in pratica

Un esempio di programma che contiene una variabile:

class UnaVar {
  public static void main(String args[]) {
    int x;

    x=10;

    System.out.println(x);
  }
}

La variabile si chiama x, è di tipo intero; il valore 10 viene memorizzato in essa; il suo valore viene stampato.


Dichiarazione di variabile

int x;

Dichiara una variabile di tipo intero, di nome x.

int
tipo intero; ossia: dice che voglio una variabile, ossia una memoria, in cui sia possibile mettere dei valori interi.
x
nome della variabile; si poteva usare un nome qualsiasi, per esempio ewrx.

Uso delle variabili

Memorizzare un valore in una variabile:

  x=10;

Significato: metti il valore 10 nella variabile.

Estrarre il valore memorizzato:

  System.out.println(x);

Significato: prendi il valore memorizzato nella variabile x e stampalo.


Variabili: rappresentazione grafica

Ogni variabile si rappresenta con una casellina

Accanto si scrive il nome della variabile.

Dentro si scrive il valore memorizzato.


Cambiare il valore in una memoria

L'istruzione x=... mette il valore in memoria, rimpiazzando quello precedente.

class Cambia {
  public static void main(String args[]) {
    int x;

    x=10;

    System.out.println(x);

    x=20;

    System.out.println(x);
  }
}

Evoluzione temporale della memoria

Cosa succede quando si esegue il programma.

Si esegue una istruzione per volta.

Le istruzioni possono cambiare i valori in memoria.


Prima istruzione

Viene dichiarata una variabile di nome x

Stato della memoria Stato di esecuzione del programma
  public static void main(String args[]) {
--> int x;

    x=10;

    System.out.println(x);

    x=20;

    System.out.println(x);
  }

In questa variabile si può mettere un intero.


Seconda istruzione

Si mette il valore 10 nella variabile.

Stato della memoria Stato di esecuzione del programma
  public static void main(String args[]) {
    int x;

--> x=10;

    System.out.println(x);

    x=20;

    System.out.println(x);
  }

Terza istruzione

Si stampa il valore che si trova nella variabile.

Stato della memoria Stato di esecuzione del programma
  public static void main(String args[]) {
    int x;

    x=10;

--> System.out.println(x);

    x=20;

    System.out.println(x);
  }

Quarta istruzione

Si mette il valore 20 nella variabile.

Stato della memoria Stato di esecuzione del programma
  public static void main(String args[]) {
    int x;

    x=10;

    System.out.println(x);

--> x=20;

    System.out.println(x);
  }

Nota: il valore cha stava prima nella variabile è stato sovrascritto.

Ogni volta che memorizzo un valore in una variabile, cancello il valore precedente.


Quinta istruzione

Si stampa il valore contenuto in x

Stato della memoria Stato di esecuzione del programma
  public static void main(String args[]) {
    int x;

    x=10;

    System.out.println(x);

    x=20;

--> System.out.println(x);
  }

Il valore in x ora è 20, per cui si stampa 20.


Domanda

Cosa stampa il seguente programma?

class CosaStampa {
  public static void main(String args[]) {
    int x;

    x=-1;
    x=2;
  }
}

Soluzione

Vengono eseguite le seguenti istruzioni:

  1. viene creata la variabile (casellina) di nome x
  2. viene messo il valore -1 in essa
  3. viene messo il valore 2

Non ci sono istruzioni di stampa.

Quindi: non viene stampato niente.

Le dichiarazioni di variabile, e il loro uso, riguardano la memoria, e non i dispositivi di output.

L'unica istruzione (vista finora) che stampa qualcosa sullo schermo è System.out.println


Più variabili nello stesso programma

Ogni variabile ha un nome.

Esempio:

class Due {
  public static void main(String args[]) {
    int x;
    int y;

    x=10;
    y=34;

    System.out.println(y);
  }
}

Cosa succede in memoria?

Per ogni variabile ho una casella

Stato della memoria Stato di esecuzione del programma
class Due {
  public static void main(String args[]) {
    int x;
--> int y;

    x=10;
    y=34;

    System.out.println(y);
  }
}

Ogni variabile è una casella diversa

L'assegnamento x=10 mette il valore 10 soltanto nella casella x

Stato della memoria Stato di esecuzione del programma
class Due {
  public static void main(String args[]) {
    int x;
    int y;

--> x=10;
    y=34;

    System.out.println(y);
  }
}

Secondo assegnamento

L'istruzione y=34 mette il valore 34 nella casella y

Il valore che sta nella casella x resta invariato.

Stato della memoria Stato di esecuzione del programma
class Due {
  public static void main(String args[]) {
    int x;
    int y;

    x=10;
--> y=34;

    System.out.println(y);
  }
}

Si stampa il valore in y, ossia 34


Stato della memoria

Quello che succede dipende solo dallo stato della memoria.

L'effetto di una istruzione dipende solo dallo stato attuale della memoria.

Il grafico della memoria è utile per capire come si comporta ogni istruzione.


Copia da una casella all'altra

Ogni variabile è una casella separata.

I valori sono in genere diversi, però si possono copiare da una casella all'altra.

class DueVar {
  public static void main(String args[]) {
    int x;
    int y;

    x=10;
    y=x;

    System.out.println(y);
  }
}

y=x significa: prendi il valore di x e copialo in y.


Copia di variabili: la memoria

Ogni volta che dichiaro una variabile, ho una nuova casella.

Stato della memoria Stato di esecuzione del programma
class DueVar {
  public static void main(String args[]) {
    int x;
--> int y;

    x=10;
    y=x;

    System.out.println(y);
  }
}

Uso delle due variabili

Quando faccio un riferimento a una variabile, uso la casella corrispondente.

Al secondo passo, metto 10 nella variabile x.

Stato della memoria Stato di esecuzione del programma
class DueVar {
  public static void main(String args[]) {
    int x;
    int y;

--> x=10;
    y=x;

    System.out.println(y);
  }
}

Copia di variabili

y=x significa che il valore di x viene preso e copiato in y.

Stato della memoria Stato di esecuzione del programma
class DueVar {
  public static void main(String args[]) {
    int x;
    int y;

    x=10;
--> y=x;

    System.out.println(y);
  }
}

L'ultima istruzione stampa il valore di y, ossia 10 (sto usando il valore che si trova memorizzato in y)


Domanda

Cosa stampa il programma che segue?

class Dopo {
  public static void main(String args[]) {
    int x; 
    int y;

    x=10;
    y=x;
    x=21;

    System.out.println(y);

    System.out.println(x);
  }
}

Risposta

x=10 mette 10 nella variabile x

y=x mette il valore di x in y, quindi 10 va in y

x=21 mette 21 in x, senza modificare il resto della memoria, per cui in y ci resta il valore che ci stava prima, cioè 10.

Si stampa il valore di y, che non è stato cambiato, quindi 10

Regola generale: l'unica istruzione che cambia il valore di una variabile y è y=...;

Conseguenza: x=21 non cambia il valore di y


Come fare calcoli

Gli operatori algebrici sono i seguenti:

+ - * /

Non si può omettere la moltiplicazione: a*b non si può scrivere ab

Esempio:

y=x*5+x;

Significato: prendi il valore memorizzato in x, moltiplicalo per 5, e somma a questo il valore che sta in x. Il risultato va memorizzato in y.


Il significato di =

Forma generale:

variabile=espressione;

Significato: calcola il valore dell'espressione, e metti il risultato nella variabile.

Se nell'espressione ci sono delle variabili, al loro posto viene messo il valore attualmente memorizzato.


Costruzione di espressioni

Regole di precedenza fra gli operatori: prima * e / e poi + e -

Gli spazi sono irrilevanti.

In caso di dubbi, si possono usare le parentesi.

class Preced {
  public static void main(String args[]) {
    int x;
    int y;

    x=10;
    y=x+10  *2;

    System.out.println(y);
  }
}

Domanda: cosa viene stampato?


Risposta

Il * ha precedenza maggiore.

x+10 *2 viene interpretato come x + (10*2)

Viene stampato 30


Esercizio

Dati due numeri, stampare il doppio della loro somma.

class SommaDue {
  public static void main(String args[]) {
    int x;
    int y;

    x=10;
    y=12;

    ...
  }
}

Inserire la soluzione al posto dei puntini.


Soluzione

Si crea una nuova variabile z

Si usa l'istruzione z=espressione per mettere in z il risultato cercato.

class SommaDue {
  public static void main(String args[]) {
    int x;
    int y;

    x=10;
    y=12;

    int z;

    z=2*(x+y);

    System.out.println(z);
  }
}

Domanda

Cosa stampa il programma che segue?

class Attuale {
  public static void main(String args[]) {
    int x;
    int y;

    y=4;
    x=10;
    y=x+1;
    x=y+4;

    System.out.println(x);
  }
}

Risposta

Ogni volta che si usa una variabile in una espressione (a destra di =), va messo il valore che è attualmente memorizzato.

Importante! Quando si esegue una espressione var=espr viene prima valutata l'espressione, e poi il valore che si trova viene messo nella variabile.


Variabili reali

Servono per memorizzare valori frazionari.

Dichiarazione:

  double nomevariabile;

Esempio:

class Reale {
  public static void main(String args[]) {
    double x;

    x=10.32/4;

    System.out.println(x);
  }
}

Al posto della virgola si usa il punto.

Viene stampato:

2.58

Si usano ancora + - * / con le stesse regole di precedenza e parentesi.


Esercizio: fare la media

Dati tre numeri frazionari, calcolare la loro media.

Completare il programma qui sotto:

class Media {
  public static void main(String args[]) {
    double a, b, c;

    a=2.2;
    b=3.3;
    c=10;

    ...
  }
}

Nota: i numeri reali includono anche tutti i numeri interi!

Il valore 10 può venire messo anche in una variabile double


Soluzione

Si dichiara una nuova variabile d, in cui si mette il risultato della media.

class Media {
  public static void main(String args[]) {
    double a, b, c;

    a=2.2;
    b=3.3;
    c=10;

    double d;

    d=(a+b+c)/3;

    System.out.println(d);
  }
}

Viene stampato:

5.166666666666667

Precisione

La soluzione è un numero periodico.

Viene invece trovato 5.166666666666667

I numeri vengono rappresentati con un numero finito di cifre.


Mantissa ed esponente

I numeri grandi non si scrivono usando tutte le cifre.

Si usano due numeri: mantissa ed esponente

Esempio: b=12.1e+2

Significato: 12.1 * 102


Mantissa ed esponente in generale

Mantissa=numero frazionario, esponente=numero intero.

Si scrive: mantissae+esponente, e significa: mantissa*10esponente

Esempio: 1e+6 significa 1*106, ossia un milione.


Altri esempi di espressioni

class Espressioni {
  public static void main(String[] args) {
    double a=12.23;
    double b=0.1e+2;
    double c;

    c=(a+b)/12.1;
    c=a*2+b;
    c=1/(a-1)/(b-4);
    c=Math.sqrt(a*a - b*b);
  }
}

Il metodo Math.sqrt calcola la radice quadrata.

Vedremo altri metodi nel seguito.


Il significato di uguale

Cosa stampa il seguente programma?

class Incr {
  public static void main(String args[]) {
    int x;

    x=4;

    x=x+1;

    System.out.println(x);
  }
}

Suggerimento: interpretazione letterale delle regole viste fino ad ora.


x=x+1

La istruzione variabile=espressione calcola il valore della espressione, e mette il risultato nella variabile.

Quando viene eseguita x=x+1 nella variabile x c'è il valore 4. Quindi x+1 ha valore 5.

Il risultato viene messo in x

Quindi, x=x+1 aumenta il valore che sta in x di uno.


La divisione intera

Regola: se i due operandi di una divisione sono interi, allora il risultato è un valore intero (troncato).

Per esempio, 14/5 fa 2.

Modo di vedere questo risultato:

/
divisione intera
%
resto

Interpretazione: / dice il risultato, mentre % dice il resto.


Esempio

Cosa stampa questo programma?

class DivInt {
  public static void main(String args[]) {
    int a;
    int b;
    int c;

    a=11;
    b=a/2;
    c=b*2;

    System.out.println(c);
  }
}

Soluzione

  1. nella variabile a viene messo 11
  2. la istruzione b=a/2 comporta due passi:
    1. viene valutato a/2; è una divisione intera, per cui viene 5 e non 5.5
    2. il risultato va in b
  3. la istruzione c=b*2 moltiplica il valore di b per due e mette il risultato in c

Importante: ogni istruzione agisce sullo stato corrente della memoria.

L'istruzione c=b*2 vede il valore di b, che è 5. Non si può ricordare che questo valore viene dalla divisione di 11 per 2.


Divisione non intera

Soluzione sbagliata: mettere il risultato in una variabile reale.

  int a;
  double b;

  ...

  b=a/2;

L'istruzione b=a/2 viene comunque eseguita in due passi.

  1. nel primo passo si fa la divisione a/2.
  2. nel secondo si mette il risultato in b

La prima divisione non può "prevedere" che il risultato verrà messo in una variabile reale.

Dato che i due operandi a e 2 sono interi, fa la divisione intera.


Divisione non intera

Dividendo due variabili, di cui una non è intera, viene usata la divisione esatta (reale).

  double a;
  double b;

  a=11;
  b=a/2;

Oppure:

  int a;
  double b;

  a=11;
  b=10/2.0;

Il valore 2.0 viene interpretato come un reale, anche se non ha parte frazionaria.


Contrazioni

Dichiarazione con assegnamento:

int x=10;

Equivale a:

int x;
x=10;

Contrazioni

Più dichiarazioni insieme:

double x, y, z;
int a, b;

Equivale a:

double x;
double y;
double z;
int a;
int b;

Si possono anche fare assegnamenti:

double a, b=10.2, c=32;

Riepilogo

  1. le variabili sono contenitori in cui si possono memorizzare dati
  2. ogni variabile ha un tipo e un nome
  3. l'istruzione var=espr mette un valore nella variabile
  4. se una variabile appare in una espressione, al suo posto si mette il suo valore
  5. si valuta prima l'espressione, e poi si mette il risultato nella variabile
  6. ogni istruzione agisce solo sulla base dello stato attuale della memoria
  7. attenzione alle precedenze (es. x+2 * 3) e ai tipi! (es. divisione intera)