Tipi di dato
e
controllo del flusso
Dott. Ing. Leonardo Rigutini
Dipartimento Ingegneria dell’Informazione
Università di Siena
Via Roma 56 – 53100 – SIENA
Uff. 0577233606
[email protected]
www.dii.unisi.it/~rigutini/
Tipi di dato
Tipi di dato semplici (primitivi)

Il JAVA fornisce tutti i tipi di dato semplici. Per ognuno di essi
inoltre la Sun ha sviluppato una “versione” ad oggetti:


i wrapper
Per i tipi di dato primitivi il JAVA non utilizza la memorizzazione
per riferimento, bensì per valore:

Questo significa che tutte le operazioni di assegnamento, passaggio
di parametri ecc… creano una variabile distinta
Tipi di dato semplici
Tipo
Dimensione
Min
Max
Wrapper
boolea
n
1 bit
-
-
char
16 bit
0
216-1
Char
byte
8 bit
-128
+127
Byte
short
16 bit
-215
+215-1
Short
int
32 bit
-231
+231-1
Integer
long
64 bit
-263
+263-1
Long
float
32 bit
IEEE 754
Float
double
64 bit
IEEE 754
Double
void
-
-
-
Boolean
Void
Tipi di dato numerici

Quando utilizziamo un tipo di dato semplice numerico è importante
ricordarsi del range limitato di numeri rappresentabile in
hardware

Piccoli errori di arrotondamento possono portare ad un risultato
scorretto anche di quantità significative a seguito di numerose
operazioni aritmetiche

Il caso più eclatante fu l’errore scoperto sul processore Pentium nel
1994 pochi mesi dopo la sua uscita
Operatori
Assegnamento

L’assegnamento permette di definire il valore memorizzato in una
variabile:

il valore assegnato deve essere compatibile col tipo della variabile,
altrimenti si genera un errore
int a, b;
float v1, v2;
char c = ‘M’;
non ammesso
a = 4;
b = a;
v1 = 3.2
v2 = a;
b = v1;
variabile  espressione
b assume il valore di a (cioè 4)
ammesso: v2 assume il valore
di a (4) convertito in float
Cast

cast (forzatura) indica l’operazione di forzare la trasformazione di un
tipo di dato ad un altro:


La sintassi consiste nell’inserire il nome_tipo tra parentesi, prima della
variabile o della espressione che vuole essere castata

int a=(int) (3,14*4);  a contiene 12 invece che 12.56 !!!

double A=3,14; int f=(int) A;  f contiene il valore 3 !!!
Il cast può essere esplicito o implicito:


cast esplicito - l’utente specifica il tipo di dato finale in cui desidera
lavorare (tra parentesi tonde)
cast implicito - il compilatore automaticamente decide il tipo di dato finale
in base al tipo di dato della variabile in cui il valore va ad essere
memorizzato. Le conversioni ammesse implicitamente sono:
byte  short  int  long  float  double
Operatori

Operatori unari: permettono di effettuare operazioni di inversione di
segno e autoincremento



positivo +, negativo –
pre-incremento ++a, pre-decremento --a
post-incremento a++, post-decremento a--
class Prova {
public static void main(String[] args) {
int A = 10;
System.out.println(A);
// Stampa 10
System.out.println(A++); // Stampa 10
System.out.println(++A); // Stampa 12
}
}
Operatori

Operatori aritmetici:




moltiplicazione *, divisione /
modulo %
addizione +, sottrazione –
Operatori relazionali: permettono di costruire espressioni logiche



uguale == , diverso !=
maggiore > , maggiore e uguale >=
minore < , minore e uguale <=
(c != 23)  è true se c è diverso da 23
(b == ‘s’)  è true se b è il carattere ‘s’
Operatori

Operatori booleani
Permettono di costruire espressioni logiche:



And &&
Or ||
Not !
( !((c == 23) || (c ==24)) )  c non è uguale a 23 nè a 24
( (b == ‘s’) || (b ==‘S’) )  è true se b è il carattere ‘s’ o ‘S’
( !((a >= 0) && (a < 0.5)) )  è false se a è compreso tra 0 (compreso) e
0.5 (escluso)

Non vengono mai valutate tutte i termini della condizione, ma solo
fino a quando il risultato è univocamente determinato:
v1 && v2 && v3 && v4  v4 non viene valutata
T
T
F
T
Operatori

Operatori bit-a-bit




And &
Or |
Xor ^
Not ~
class ProvaXor {
public static void main(String[] args) {
boolean A = 0x80; // (1000 0000)2
boolean B = 0xAB; // (1010 1011)2
System.out.println(A ^ B); // Stampa 0x2B (0010 1011)2
}
}
Operatori

Operatori di shift
Permettono di traslare a destra o a sinistra sequenze di bit:


shift a destra >>
shift a sinistra <<
1001001011101101 >> 2  0010010010111011
1001001011101101 << 3  0010010111011000
Varianti di operatori

Per quasi tutti gli operatori è possibile sostituire una espressione del
tipo
variabile = variabile <operatore> valore
con una forma abbreviata:
variabile <_varoperatore>= valore
double A = 0.0D;
// Invece di scrivere A = A + 2D
// abbiamo scritto A += 2.0D
System.out.println(A += 2.0D); // Stampa 2.0
System.out.println(A /= 2.0D); // Stampa 1.0
Confronto di oggetti

Quando utilizziamo l’operatore == per confrontare due oggetti, in
realtà confrontiamo l’indirizzo memorizzato nelle due variabili:



Tale confronto quindi ritorna true nel caso che entrambe le variabili
si riferiscano allo stesso oggetto
Quindi in questo caso l’uguaglianza non si riferisce al contenuto
della variabile ma controlla se le due variabili indicano lo stesso
oggetto
Normalmente ogni oggetto mette a disposizione un metodo per
controllare l’uguaglianza tra due oggetti:

String.equals() ecc…
Confronto di oggetti

Solamente per i tipi di dato primitivi il confronto si comporta
effettivamente come un operatore matematico di uguaglianza:


Es. due variabili intere diverse che contengono lo stesso valore
sono considerate uguali
Un riferimento ad oggetto può avere valore null
Tale valore può essere utilizzato per verificare su un oggetto è
stato inizializzato tramite confronto:
Rectangle R;
if (R==null) … // l’oggetto R non è stato inizializzato

Array
Array

Un array è un handle ad un vettore (o una matrice) di elementi che
possono essere di tipo primitivo oppure oggetti:
int[] A1;
int A2[];
int[] B = {1, 2, 3, 4, 5, 6};

in entrambi i casi viene
generato un handle ad
un vettore
in questo caso viene anche
allocata la zona di memoria
necessaria a contenere gli
elementi indicati
Se vogliamo allocare memoria:
int[] A1;
int A2[];
int[] B = {1, 2, 3, 4, 5, 6};
A1 = new int[6];
A2 = A1;
A1.length indica quanti
elementi sono stati allocati
Array di oggetti

È anche possibile creare un array di oggetti, cioè un vettore di
handle tutti inizializzati a null
0: NULL
Segmento[] Spezzata;
Spezzata = new Segmento[6];
for ( int i = 0; i < Spezzata.length; i++) {
Spezzata[i] = new Segmento();
}

1:
NULL
2:
NULL
3:
NULL
4:
NULL
5:
NULL
E anche possibile inizializzare direttamente un vettore di oggetti:
Segmento[] Spezzata = {
new Segmento();
new Segmento();
new Segmento();
};
ma è poco utile
Array multidimensionali

Il JAVA non pone limiti al numero di dimensioni degli array
A[0][3]
int[][] A = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10}
};
int[][] B = new int[5][2];
int[][][] A = new [2][2][3];
for (int x = 0; x < A.length; x++)
for (int y = 0; y < A[x].length; y++)
for (int z = 0; z < A[x][y].length; z++)
A[x][y][z] = 1;
A.length
1 2 3 4 5 
6 7 8 9 10


A[i].length
Controllo del flusso
if … else …
if (boolean-cond) {
blocco 1
}
else {
blocco 2
}
cond
false
true
if (vendite > media) {
bonus = 0.1;
guadagno = quota * bonus;
}
else {
guadagno = 0;
}
blocco 1
blocco 2
Operatore ?
Il costrutto if … else … può essere condensato in una istruzione
singola utilizzando l’operatore ?
condizione ? valore1 : valore2

y = x>=0 ? x : -x ;
errore
y = if (x>=0) x; else -x;
if (x >=0)
y=x;
else
y=-x;
if … else if … else …
if (cond1) {
blocco 1
}
else {
if (cond2) {
blocco 2;
}
else {
blocco3;
}
}
cond1
false
true
cond2
if (cond1) {
blocco 1
}
else if (cond2) {
blocco 2;
}
else {
blocco3;
}
false
blocco 1
true
blocco 2
blocco 3
switch … case …
switch (variabile) {
case Valore1: blocco1
break;
case Valore2: {
blocco2;
break;
}
default: blocco default;
}
char C = ‘n’;
switch (C) {
case ‘n’: System.out.println(“Sconto”);
break;
case ‘s’: System.out.println(“Sconto no”);
break;
default: System.out.println(“Boh!”);
}
while ()
while (boolean-cond) {
blocco
}
cond
true
blocco

Ciclo infinito:
while (true) {
System.out.println(“Infinito”);
}
false
do … while()

La condizione viene valutata dopo aver eseguito il blocco almeno
una volta
do {
blocco
} while (boolean-cond)
blocco
cond
false
true
Cicli determinati: for
for (inizializzazione; boolean-cond; incremento) {
blocco
}

Ciclo di 5 iterazioni:
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
inizializzazione
cond
true
blocco

Ciclo infinito:
for (;;) {
System.out.println(“Infinito”);
}
incremento
false
for multivariabile


È possibile specificare nel ciclo for condizioni per più variabili.
L’esecuzione dei due cicli avviene eseguendo prima il più interno e
poi avanzando quello superiore:
for (int i = 0, j = 5; i < 5; i++, j--)
{
System.out.println(i);
System.out.println(j);
}
break e continue

Queste istruzioni modificano l’esecuzione del ciclo:


break interrompe l’attuale istruzione di iterazione while, do while, for ...
ed esce definitivamente dalla iterazione
continue interrompe la corrente iterazione e ritorna all’inizio del ciclo,
iniziandone un’altra
for (int i = 0, j = 10; i < 15; i++, j--) {
System.out.println(i);
if (i % 2 == 0)
continue;
if (j < 0)
break;
System.out.println(j);
}
Scarica

3. tipi di dato