Numeri, espressioni, calcoli, caratteri, input

Numeri, espressioni, calcoli,
caratteri, input
Interi e decimali
Definizione di costanti
Espressioni
Funzioni matematiche
Classi involucro
Il tipo char
Acquisizione di input
Laboratorio di Programmazione
Luca Tesei
1
Una classe Borsellino
/** Realizza un borsellino per le monete. Registra il
numero di monete e calcola il valore totale
*/
public class Purse {
/** Costruisce un borsellino vuoto
*/
public Purse() {
}
/** Aggiunge monete di tipo "nickel" al borsellino
@param count il numero di nickel da aggiungere
*/
public void addNickels(int count) {
}
Laboratorio di Programmazione
Luca Tesei
2
Classe Borsellino cont’d
/** Aggiunge monete di tipo "dime" al borsellino
@param count il numero di dime da aggiungere
*/
public void addDimes(int count) {
}
/** Aggiunge monete di tipo "quarter" al borsellino
@param count il numero di quarter da aggiungere
*/
public void addQuarters(int count) {
}
/** Ispeziona il valore totale delle monete nel borsellino
@returns la somma dei valori di tutte le monete attualmente
presenti
*/
public double getTotal() {
}
}
Laboratorio di Programmazione
Luca Tesei
3
Esempio d’uso
Purse myPurse = new Purse();
myPurse.addNickels(3);
myPurse.addDimes(1);
myPurse.addQuarters(2);
double totalValue =
myPurse.getTotal();
● totalValue conterrà 0,75 cioè il valore in dollari
delle monete contenute nel borsellino
Laboratorio di Programmazione
Luca Tesei
4
Numeri interi e numeri decimali
●
●
●
●
●
Per rappresentare quantità che si contano naturalmente
con multipli di 1 (positivi o negativi) usiamo variabili di
tipo intero (int)
Nell’esempio del borsellino int è il tipo dei parametri dei
metodi addXXX
Questo perché è naturale considerare le monete come
quantità indivisibili e quindi quantificate con un numero
intero
Il metodo getTotal() invece restituisce un double
Questo perché è naturale per un valore che rappresenta
una quantità di dollari avere dei decimali
Laboratorio di Programmazione
Luca Tesei
5
Primi passi per
l’implementazione di Purse
Ogni oggetto di tipo Purse può essere descritto
dalla quantità di nickels, dimes e quarters che
contiente
● Inseriamo quindi tre variabili istanza di tipo int
per rappresentare queste quantità
...
private int nickels;
private int dimes;
private int quarters;
●
Laboratorio di Programmazione
Luca Tesei
6
Primi passi per
l’implementazione di Purse
public double getTotal() {
return nickels * 0.05 + dimes * 0.1
+ quarters * 0.25;
}
●
L’ * indica la moltiplicazione (perché • o × non si trovano
generalmente nelle tastiere)
● L’espressione dopo return segue le regole di
associatività e precedenza tipiche dell’aritmetica (la
grammatica di Java per le espressioni segue le regole che
abbiamo visto a Programmazione)
● Il valore ottenuto è un numero in virgola mobile poiché
moltiplicando un intero per un numero decimale si ottiene
un numero decimale, in generale
Laboratorio di Programmazione
Luca Tesei
7
Costanti numeriche
●
●
●
●
Nelle costanti numeriche che si possono
scrivere nel codice la virgola deve essere
indicata come punto decimale
Si può usare anche la notazione esponenziale
Ad esempio 5,0 × 10-3 si scrive come 5.0E-3
Cioè si usa il punto decimale e si scrive E
seguito dall’esponente di × 10
Laboratorio di Programmazione
Luca Tesei
8
Numeri interi
●
●
●
●
Un numero intero è un numero senza decimali
che può essere sia positivo che negativo
Il tipo base Java corrispondente ai numeri interi
è int
Una variabile int può contenere i numeri interi
da –2147483648 a +2147483647
31 bit + 1 bit per il segno = 32 bit di memoria
allocati per ogni variabile int
Laboratorio di Programmazione
Luca Tesei
9
Numeri interi
Esistono altri tipi base di interi che possono
rappresentare meno o più numeri di int
• short: 16 bit - Range: da -215 a 215-1
• byte: 8 bit - Range da –27 a 27-1
• long: 64 bit - Range da –263 a 263 –1
●
Laboratorio di Programmazione
Luca Tesei
10
Numeri in virgola mobile
●
●
●
●
●
Possono contenere cifre decimali
Contengono un certo numero di cifre significative e la
posizione della virgola
Es. 250 25 0.25 0.025 hanno tutti le stesse cifre
significative (25), ciò che cambia è la posizione della
virgola (da qui “virgola mobile”)
Naturalmente la rappresentazione in realtà è in base 2
In java la virgola è rappresentata dal punto decimale
come nella notazione anglosassone (come tutte le
calcolatrici del resto)
Laboratorio di Programmazione
Luca Tesei
11
Numeri in virgola mobile
• double può rappresentare circa 15 cifre
significative: è il tipo con maggiore precisione
(“doppia precisione”)
• float può rappresentare circa 7 cifre
significative: precisione spesso insufficiente, ma
calcoli più veloci
● Per precisione si intende la grandezza degli
errori dovuti all’ arrotondamento che
inevitabilmente si commettono con l’uso di
questi numeri
Laboratorio di Programmazione
Luca Tesei
12
Precisione
public class ProvaPrecisione {
public static void main(String [] argv) {
double originalPrice = 3E14;
double discountedPrice = originalPrice –
0.05;
double discount = originalPrice –
discountedPrice;
// dovrebbe essere 0.05
System.out.println(discount);
// stampa 0.0625 – Errore dovuto
//all’arrotondamento da rappresentazione
}
}
Laboratorio di Programmazione
Luca Tesei
13
Numeri rappresentabili
●
●
Il tipo float può rappresentare il range dei
numeri, positivi o negativi, con valore assoluto
che va da 2-149 a (2-2-23)•2127
Il tipo double può rappresentare il range dei
numeri, positivi o negativi, con valore assoluto
che va da 2-1074 a (2-2-52)•21023
Laboratorio di Programmazione
Luca Tesei
14
Numeri a lunghezza e
precisione arbitraria
●
●
Il pacchetto java.math contiene una classe
BigInteger i cui oggetti possono
rappresentare numeri interi di lunghezza
arbitraria
Lo stesso pacchetto contiene una classe
BigDecimal i cui oggetti possono
rappresentare numeri a virgola mobile con
precisione arbitraria
Laboratorio di Programmazione
Luca Tesei
15
Numeri a lunghezza e
precisione arbitraria
•
•
Per questi numeri non si possono usare i normali
operatori + * - / =
I corrispondenti metodi add, multiply, subtract, divide
ed equals sono forniti dalle relative classi:
BigInteger a = new BigInteger(“123456789”);
BigInteger b = new BigInteger(“987654321”);
BigInteger c = a.multiply(b);
System.out.println(c);
// stampa 121932631112635269
•
Naturalmente i calcoli con questi numeri sono più lenti
di quelli fatti con i numeri dei tipi base
Laboratorio di Programmazione
Luca Tesei
16
Costruttore di Purse
Public Purse() {
nickels = 0;
dimes = 0;
quarters = 0;
}
● Il costruttore di default farebbe esattamente la
stessa cosa, ma lo specifichiamo per chiarezza
Laboratorio di Programmazione
Luca Tesei
17
Implementazione di addNickels
public void addNickels(int count) {
nickels = nickels + count;
}
● È la tipica istruzione di incremento di un valore
● L’assegnamento prima valuta la parte a sinistra dell’= e
quindi considera il valore corrente della variabile
istanza intera nickels al quale aggiunge il valore di
count
● Il valore così ottenuto sarà assegnato alla variabile
istanza nickels, cioè sarà il suo valore dopo
l’esecuzione dell’istruzione (si può pensare che sia il
valore che nickels ha dopo il ; finale)
Laboratorio di Programmazione
Luca Tesei
18
Altre istruzioni di incremento
In Java, come in C, esiste una forma abbreviata
per l’incremento
nickels = nickels + count;
può essere scritta equivalentemente come
nickels += count;
● La stessa abbreviazione si può usare anche per
gli altri operatori (*, /, -):
P *= q; // equivalente a p = p * q;
●
Laboratorio di Programmazione
Luca Tesei
19
Incremento di 1
Un’istruzione che ricorre molto frequentemente
nei programmi è l’incremento o il decremento di
una variabile intera di una unità
● In Java, come in C, esistono abbreviazioni
speciali per questi casi:
i++; // equivalente a i = i + 1; e a i +=1;
i--; // equivalente a i = i – 1; e a i -=1;
●
Laboratorio di Programmazione
Luca Tesei
20
Costanti
public double getTotal() {
return nickels * 0.05 +
dimes * 0.1 +
quarters * 0.25;
}
●
●
La maggior parte del codice si documenta da
sé, ma in questo caso i numeri 0.05, 0.1 e 0.25
compaiono senza nessuna spiegazione
È buona regola evitare di inserire nel codice
questi “numeri magici”
Laboratorio di Programmazione
Luca Tesei
21
Costanti
●
●
●
●
Le costanti possono essere pensate come dei nomi a
cui è associato un valore
Tale associazione rimane valida per tutta la vita della
costante e non cambia mai
In genere, per convenzione, le costanti sono scritte
tutte maiuscole e si usa l’underscore come separatore
nel caso che il nome sia composto da più parole
In Java una costante si dichiara come una variabile (di
frame) usando la parola chiave final e inizializzando
il valore nella dichiarazione
Laboratorio di Programmazione
Luca Tesei
22
Costanti
public double getTotal() {
final double NICKEL_VALUE = 0.05;
final double DIME_VALUE = 0.1;
final double QUARTER_VALUE = 0.25;
return nickels * NICKEL_VALUE +
dimes * DIME_VALUE +
quarters * QUARTER_VALUE;
}
Laboratorio di Programmazione
Luca Tesei
23
final
●
●
In generale in Java la parola chiave final indica
un qualcosa che non può essere più modificato
(vedremo che esistono, oltre alle variabili, anche
classi final, cioè che non possono essere
estese)
Il compilatore dà errore se si cerca di modificare
una variabile final.
Laboratorio di Programmazione
Luca Tesei
24
Costanti
●
●
●
●
La dichiarazione di una variabile con lo
specificatore final ha lo stesso effetto di una
qualsiasi altra definizione di variabile
Viene cioè allocata la nuova variabile sul frame
corrente dell’attivazione corrente
Al momento della chiusura del blocco del frame
in cui è stata definita essa scompare
E’ il controllo del compilatore che la rende non
modificabile
Laboratorio di Programmazione
Luca Tesei
25
Costanti
●
●
●
In genere però le costanti sono utili in diversi
metodi della stessa classe
Per evitare di dover ridefinire le variabili final in
ogni metodo che le usa (ed evitare anche errori
se il valore viene modificato solo in alcuni
metodi, ad esempio in un’altra versione del
programma) possiamo pensare di associare le
costanti direttamente alla classe
Per definire costanti che si riferiscono ad una
classe si può usare lo specificatore static
Laboratorio di Programmazione
Luca Tesei
26
static
●
●
●
●
Lo specificatore static deriva dal C e il suo
nome può risultare fuorviante
In Java, se nella definizione di una classe viene
inserita una variabile istanza con lo
specificatore static, quella variabile istanza va
considerata come elemento della classe
In genere le variabili istanza formano lo stato di
ogni oggetto della classe che viene creato
Le variabili istanza static invece non vanno a far
parte dello stato degli oggetti della classe, ma
fanno parte della definizione della classe stessa
Laboratorio di Programmazione
Luca Tesei
27
static
●
●
●
●
Esiste una sola copia di una variabile istanza
static di una classe e si riferisce all’intera classe
Per riferirla e/o modificarla si usa la notazione
NomeClasse.nomeVariabileIstanzaStatic
Alle variabili istanza static possono essere
associati tutti i possibili specificatori di accesso:
public, private e protected
Inoltre possono essere final, cioè costanti di
classe
Laboratorio di Programmazione
Luca Tesei
28
Esempio
●
●
●
●
Vedremo più avanti degli esempi in cui sono utili
variabili static di classe
Per adesso useremo questa possibilità solo per
specificare costanti
Nel nostro caso le costanti che indicano il valore
di ogni moneta sembrano essere utili solo nel
contesto della classe Purse e quindi le
dichiariamo private
Molte classi delle API hanno invece delle
costanti pubbliche che si possono usare
Laboratorio di Programmazione
Luca Tesei
29
Esempio
public class Purse {
...
private static final double
NICKEL_VALUE = 0.05;
private static final double
DIME_VALUE = 0.1;
private static final double
QUARTER_VALUE = 0.25;
...
}
Laboratorio di Programmazione
Luca Tesei
30
Esempio
●
All’interno dei metodi della classe si possono riferire le
variabili static (sia final che non) semplicemente con il
loro nome (nel caso di conflitto va invece specificato il
nome completo (cioè NomeClasse.nomeVariabile), ad
esempio Purse.NICKEL_VALUE
public double getTotal() {
return nickels * NICKEL_VALUE +
dimes * DIME_VALUE +
quarters * QUARTER_VALUE;
}
Laboratorio di Programmazione
Luca Tesei
31
Operazioni fra interi e decimali
●
●
●
●
In Java gli operatori + - * / si possono combinare
come si vuole insieme a costanti numeriche, variabili di
frame, variabili istanza e chiamate di metodi per
ottenere espressioni aritmetiche
Gli operandi possono essere sia numeri interi (byte,
short, int, long) che numeri in virgola mobile
(float, double)
Il risultato è un intero solo se tutti gli operandi sono
interi
Basta che un solo operando si in virgola mobile perché
il valore di tutta l’espressione sia in virgola mobile
Laboratorio di Programmazione
Luca Tesei
32
Espressioni aritmetiche
La grammatica per le espressioni aritmetiche che si
possono scrivere in Java è la seguente:
EE+T|E–T|T
TT*F|T/F|F
F  -<Op> | <Op>
<Op>  (E) | <Num> | <Ide> | <DotExpr>
● La grammatica implementa le regole tipiche di
associatività e precedenza degli operatori
● F è un ulteriore livello di precedenza per l’operatore
unario – (che lega più di tutti) usato per cambiare il
segno a un operando
●
Laboratorio di Programmazione
Luca Tesei
33
Espressioni aritmetiche
●
●
●
<Num> è un simbolo non terminale che genera tutte le
possibili costanti numeriche (intere e decimali, con o
senza notazione esponenziale)
<Ide> è un simbolo non terminale che genera tutti i
possibili identificatori Java
<DotExpr> è un simbolo non terminale che genera
tutte le possibili espressioni formate da nomi e/o
chiamate di metodi separate da punti (ad esempio
myPurse.getTotal() rappresenta un double,
this.nickels rappresenta un int all’interno di un
metodo della classe Purse )
Laboratorio di Programmazione
Luca Tesei
34
Espressioni aritmetiche
●
Esempi:
–7 * 4
 valore 28 (int)
– 11 + 2.0 / 4
 valore 11.5 (double)
– (11 + 2.0) / 4  valore 3.25 (double)
– this.nickels * this.getTotal() – 3 * 7
 supponendo che il valore della variabile istanza
nickel dell’oggetto this sia 3 (int) e che il totale
this.getTotal() sia 12.5 (double) si ottiene un valore
double a causa del valore double dell’operando
this.getTotal(). Il valore è 16.5
Laboratorio di Programmazione
Luca Tesei
35
Divisione
●
●
●
●
●
●
Bisogna prestare un’attenzione particolare al
simbolo /
In Java esso rappresenta sia la divisione usuale
che la divisione intera
Viene applicata la divisione intera se entrambi
gli operandi sono interi
La divisione intera restituisce solo la parte intera
del risultato!
7 / 4  valore 1! Non 1.75!
7 / 4.0  valore 1.75 (4.0 non intero)
Laboratorio di Programmazione
Luca Tesei
36
Resto della divisione intera
●
●
●
Il simbolo % è un operatore binario che si può
applicare solo fra due interi
Calcola il resto della divisione intera fra il primo
e il secondo
7 % 4  valore 3
Laboratorio di Programmazione
Luca Tesei
37
Errore comune
L’overloading del simbolo / porta spesso ad errori logici
difficili da individuare
● Ad esempio:
...
int p1 = 21; // punteggio prima prova
int p2 = 24; // punteggio seconda prova
int p3 = 22; // punteggio terza prova
double media = (p1 + p2 + p3) / 3;
System.out.println(media); /* Stampa 22.0!
Non 22.3333333!! */
●
Laboratorio di Programmazione
Luca Tesei
38
Errore comune
Per ottenere il risultato che vogliamo bisogna fare in
modo che almeno uno degli operandi sia un double
// Se un intero viene assegnato a una variabile
// di tipo double viene convertito a double
double totale = p1 + p2 + p3;
// totale è un valore double
double media = totale / 3;
●
Oppure
double media = (p1 + p2 + p3) / 3.0;
Laboratorio di Programmazione
Luca Tesei
39
Metodi static
●
●
●
●
La classe java.lang.Math (consultare le API) è
una collezione di costanti e metodi static
Abbiamo già visto che una variabile istanza
dichiarata come static si riferisce alla classe
e ne esiste un’unica copia (non viene inserita
nello stato degli oggetti della classe che
vengono creati)
Anche un metodo può essere dichiarato come
static e, analogamente, esso si riferisce alla
classe
È analogo a una funzione del C
Laboratorio di Programmazione
Luca Tesei
40
Metodi static
●
●
●
●
Un metodo static non può essere invocato su un
oggetto della classe
L’unico modo per mandare in esecuzione il metodo
static è quello di scrivere
NomeClasse.nomeMetodo(parametri);
All’interno di un metodo statico non è disponibile il
parametro implicito this (poiché non c’è nessun
oggetto su cui il metodo è stato invocato)
Per il resto il meccanismo di esecuzione è analogo a
quello dei metodi non statici (in particolare la creazione
di una nuova attivazione e il meccanismo di passaggio
e gestione dei parametri espliciti)
Laboratorio di Programmazione
Luca Tesei
41
Funzioni e costanti
matematiche
●
●
●
●
●
●
Definite nella classe java.lang.Math come costanti
e metodi static
Pi greco: Math.PI
Base dei logaritmi naturali: Math.E
Radice quadrata:
double radiceDi2 = Math.sqrt(2);
Coseno:
double cosenoDiPiGrecoMezzi =
Math.cos(Math.PI / 2);
Consultare le API per vedere tutte le altre funzioni
disponibili
Laboratorio di Programmazione
Luca Tesei
42
Conversioni di tipi
Il compilatore esegue alcune conversioni di tipo
implicitamente:
● Quando un valore intero viene assegnato ad una
variabile double o float, il valore viene convertito in
double o float automaticamente
...
double pippo = 4; // 4 è una costante intera
System.out.println(pippo); // Stampa 4.0
● 4.0 è la rappresentazione di una costante a virgola
mobile (c’è il punto decimale)
●
Laboratorio di Programmazione
Luca Tesei
43
Conversioni esplicite
La conversione precedente viene eseguita
automaticamente perché non comporta nessuna
perdita di informazione (i numeri interi hanno i loro
corrispondenti nei numeri a virgola mobile)
● Quando un assegnamento, invece, può provocare una
perdita di informazione viene segnalato dal
compilatore come errore
● Una errore di questo genere si ha, ad esempio,
quando si tenta di assegnare un valore a virgola
mobile ad una variabile intera
int prova = 3.5; // Errore di
// compilazione
●
Laboratorio di Programmazione
Luca Tesei
44
Conversioni esplicite
Per forzare il compilatore ad accettare
l’assegnamento (se si vuole accettare la perdita
di informazione che ne deriva) si deve fare una
conversione di tipo esplicita
● Questa operazione si chiama casting
int prova = (int)3.5; // accettato
● L’effetto di questo casting è di buttare via la
parte decimale del numero a virgola mobile e di
assegnare a prova solo la parte intera 3
●
Laboratorio di Programmazione
Luca Tesei
45
Casting
●
●
●
●
Il casting si può fare fra diversi tipi base
Ogni volta che si fa si accetta la possibilità di
perdere informazione
Ad esempio, facendo un casting da double a
float si potranno perdere alcune cifre
significative
Così come facendo un casting da int a short
Laboratorio di Programmazione
Luca Tesei
46
Casting
L’operatore di casting (il tipo tra parentesi) lega
più degli operatori aritmetici
double total = 3.456;
int prova = (int) total * 100;
● Esegue il casting su total e il valore di prova
sarà 300
int prova = (int)(total * 100);
● Esegue il casting sul valore della moltiplicazione
e il valore di prova sarà 345
●
Laboratorio di Programmazione
Luca Tesei
47
Arrotondamenti
Il casting da valori a virgola mobile a interi produce
come risultato la parte intera del valore, anche se il
valore è molto prossimo al valore intero successivo
int prova = (int) 4.99; // prova vale 4
● Per eseguire gli arrotondamenti secondo la regola
usuale (se il primo decimale è da 0 a 4 si prende la
parte intera, altrimenti la parte intera + 1) si può usare
il metodo static Math.round (consultare le API: il
valore restituito da Math.round è un long! Quindi
bisogna fare un ulteriore casting se si vuole assegnare
il risultato ad un int)
●
Laboratorio di Programmazione
Luca Tesei
48
Classi involucro
●
●
●
●
Ognuno dei tipi base di Java ha una classe
corrispondente nel pacchetto java.lang
(consultare le API)
Queste classi vengono dette classi involucro
Gli oggetti di queste classi possono un valore
del tipo base corrispondente
La vera utilità sta nelle costanti e nei metodi
statici che forniscono
Laboratorio di Programmazione
Luca Tesei
49
Classe Integer
●
●
●
●
●
Prendiamo ad esempio la classe java.lang.Integer
Un oggetto di questa classe può contenere un valore
intero
Tale valore non si trova in una variabile di frame come
i soliti int
Si trova nello heap all’interno dell’oggetto
corrispondente
Costanti static utili della classe:
–
–
Integer.MIN_VALUE (minimo numero int rappresentabile
Integer.MAX_VALUE (massimo int rappresentabile)
Laboratorio di Programmazione
Luca Tesei
50
Classe Integer
Metodi statici pubblici utili della classe Integer
public static int parseInt(String s)
● Cerca di interpretare il contenuto della stringa s
come la rappresentazione di una costante intera:
• Integer.parseInt(“15”) restituisce l’intero
15
●
Laboratorio di Programmazione
Luca Tesei
51
Classe Integer
●
●
●
●
Se la stringa contiene dei caratteri che non possono
essere considerati la rappresentazione di un intero
allora il metodo parseInt lancerà un’eccezione
Le eccezioni sono il meccanismo di base di Java per
gestire gli errori
Per adesso non gestiamo questa eccezione, vedremo
più avanti come si fa
Se un’eccezione non viene gestita (il termine giusto
sarebbe “catturata”) il programma termina con errore
indicando quale eccezione si è verificata e la pila di
attivazioni corrente (ci permette di risalire al punto
preciso del programma in cui si è verificata)
Laboratorio di Programmazione
Luca Tesei
52
Lettura di dati in input
•
Vediamo due modi per acquisire dei dati di
input dall’utente:
1. Tramite una finestra grafica di dialogo
2. Tramite lo standard input (la console, ma in
generale può essere un qualunque file)
– I dati in input rendono il programma interattivo
e possono fare in modo che il comportamento
dello stesso programma sia diverso se
vengono dati input diversi
Laboratorio di Programmazione
Luca Tesei
53
Finestra di dialogo
Possiamo chiedere all’utente di inserire una stringa e
possiamo trattare l’oggetto corrispondente nel nostro
programma
● La classe che ci serve per far apparire la finestra è
javax.swing.JOptionPane (consultare API)
● Questa classe ha diversi metodi static
showInputDialog che restituiscono un oggetto
String
● Per far apparire la finestra e ottenere l’input:
String input =
JOptionPane.showInputDialog(
“Quanti nickel hai?”);
●
Laboratorio di Programmazione
Luca Tesei
54
Finestra di dialogo
●
La stringa che passiamo come parametro sarà
visualizzata sulla finestra
Laboratorio di Programmazione
Luca Tesei
55
Finestra di dialogo
●
●
●
●
L’utente è libero di digitare qualunque cosa nel
campo di input
Poi potrà fare click sui pulsanti OK o Annulla
Se l’utente fa click su Annulla viene restituito il
valore null e la variabile String input varrà
quindi null
Se l’utente fa click su OK viene creato un
oggetto String che contiene la stringa inserita
e il suo riferimento viene assegnato alla
variabile input
Laboratorio di Programmazione
Luca Tesei
56
Esempio di uso
import javax.swing.JOptionPane;
public class InputTest {
public static void main(String argv[]) {
String input = JOptionPane.showInputDialog(
"Quanti nickel hai?");
// Utilizzo il metodo parseInt per ottenere
// il numero intero digitato
int nickels = Integer.parseInt(input);
System.out.println(nickels);
// Nei programmi che usano la grafica si deve usare
// questa chiamata per terminare il programma
System.exit(0);
}
}
Laboratorio di Programmazione
Luca Tesei
57
Esempio
●
●
●
●
Naturalmente si dovrebbe gestire sia il caso in cui
l’utente fa click su Annulla sia il caso in cui quello che
digita non è un intero
Ancora non abbiamo gli strumenti per farlo
Per adesso ci accontentiamo di un programma che, se
qualcosa va storto, termina con errore
Ricordarsi sempre di inserire System.exit(0);
come ultima istruzione del main, altrimenti il
programma resta in esecuzione (il gestore della grafica
rappresenta un processo della nostra applicazione che
rimane attivo fino a quando non lo si chiude
esplicitamente con il metodo static System.exit)
Laboratorio di Programmazione
Luca Tesei
58
Il tipo base char
●
●
●
●
●
Il tipo base char rappresenta i caratteri
Come sappiamo Java gestisce tutto il set di
caratteri Unicode
Per indicare un carattere basta inserirlo tra due
apici singoli: ‘a’
Ogni sequenza di escape corrisponde a un
carattere ‘\n’, ‘\t’, ‘\u009F’
Un carattere ha associato un valore numerico
reperibile con Character.getNumericValue
Laboratorio di Programmazione
Luca Tesei
59
Caratteri e Stringhe
●
●
●
●
●
●
‘h’ è un char
“h” è una stringa, quindi un oggetto dello Heap,
che contiene un solo carattere ‘h’
“Pippo”.charAt(0) ritorna il carattere ‘P’
Nelle stringhe i caratteri sono numerati da 0 in
su
“Pippo”.length() ritorna 5, la lunghezza della
stringa
Consultare le API
Laboratorio di Programmazione
Luca Tesei
60
Input da console
●
●
●
Oltre che da una finestra di dialogo l’input può essere
prelevato da uno stream di ingresso
In Java, così come in C e in altri linguaggi, esiste uno
stream apposito per questo che viene chiamato
standard input
Conosciamo già System.out, che è lo standard
output, e sappiamo che è un oggetto della classe
java.io.PrintStream
• System.in è un oggetto della classe
java.io.InputStream ed è lo standard input
Laboratorio di Programmazione
Luca Tesei
61
Ottenere l’input
●
●
●
●
Un oggetto della classe InputStream, quale è
System.in, è in grado di leggere un byte per
volta dallo stream che rappresenta
Non è molto comodo
Quello che vorremmo è poter ottenere, come
con la finestra di dialogo, una stringa di input
Per prima cosa bisogna incapsulare l’oggetto
System.in, di tipo InputStream, in un
oggetto della classe
java.io.InputStreamReader
Laboratorio di Programmazione
Luca Tesei
62
Ottenere l’input
●
●
●
●
Un oggetto della classe InputStreamReader
interpreta i byte di un oggetto InputStream come
caratteri (tipo base char di Java)
È un passo avanti per arrivare al nostro
obiettivo
I costruttori di questi oggetti richiedono sempre
come argomento un’oggetto della classe
InputStream
Possiamo quindi usare System.in
Laboratorio di Programmazione
Luca Tesei
63
Ottenere l’input
InputStreamReader reader = new
InputStreamReader(System.in);
• reader può restituire l’input sotto forma di un
carattere per volta (guardare le API e scoprire come
mai il metodo read restituisce un int piuttosto che
un char)
●
●
Possiamo ottenere di meglio
Gli oggetti della classe
java.io.BufferedReader possono restituire
stringhe formate da caratteri di uno stream di
caratteri
Laboratorio di Programmazione
Luca Tesei
64
Ottenere l’input
BufferedReader console = new
BufferedReader(reader);
●
●
Il costruttore richiede un oggetto della classe
java.io.Reader, di cui
InputStreamReader è una sottoclasse
Possiamo quindi passare il nostro oggetto
System.in, incapsulato nell’oggetto reader di
tipo InputStreamReader, al costruttore e
ottenere l’oggetto riferito da console
Laboratorio di Programmazione
Luca Tesei
65
Ottenere l’input
●
●
Sugli oggetti della classe BufferedReader è
possibile chiamare il metodo readLine() che
restituisce una stringa contentente una linea di
testo
Questo è quello che volevamo ottenere
Laboratorio di Programmazione
Luca Tesei
66
Ottenere l’input
Ricapitolando:
InputStreamReader reader = new
InputStreamReader(System.in);
●
BufferedReader console = new
BufferedReader(reader);
Oppure
BufferedReader console = new
BufferedReader(new
InputStreamReader(System.in));
●
Laboratorio di Programmazione
Luca Tesei
67
Ottenere l’input
A questo punto:
String input = console.readLine();
●
●
●
●
Aspetta fino a quando l’utente non digita una
linea di testo e preme Invio
La linea scritta è contenuta nella stringa riferita
da input
A questo punto possiamo fare il parsing della
stringa con i metodi delle classi involucro se ci
aspettiamo l’inserimento di un valore di un certo
tipo (es Integer.parseInt)
Laboratorio di Programmazione
Luca Tesei
68
IOException
●
●
●
●
●
Abbiamo già visto che il metodo Integer.parseInt
può sollevare un’eccezione se la stringa passata non
contiene le cifre di un intero
Anche il metodo readLine della classe
BufferedReader può sollevare un’eccezione se
qualcosa va storto con il reperimento dell’input
L’eccezione è del tipo IOException
L’eccezione IOException è un’eccezione che deve
essere gestita obbligatoriamente
Nel caso non la si voglia gestire si deve esplicitare che
il metodo che stiamo scrivendo la può sollevare
Laboratorio di Programmazione
Luca Tesei
69
Throws
●
Nel nostro caso il metodo che chiama
readLine è il main
Siccome ancora non abbiamo visto come
gestire l’eccezione dobbiamo esplicitamente
dichiarare che non la gestiamo scrivendo
public static void main(String[]
argv) throws IOException {
●
...
}
Laboratorio di Programmazione
Luca Tesei
70
Un programma di esempio
import java.io.*;
public class InputDaConsole
{
public static void main(String argv[]) throws
IOException {
BufferedReader console = new
BufferedReader(new
InputStreamReader(System.in));
System.out.println("Quanti nickels hai?");
String input = console.readLine();
int nickels = Integer.parseInt(input);
System.out.println("Hai scritto " + nickels);
}
}
Laboratorio di Programmazione
Luca Tesei
71
Classe Scanner
●
●
●
●
Dalla versione 1.5 della jdk è disponibile una
classe java.util.Scanner
Un oggetto di questa classe permette di
scorrere un flusso di caratteri o una stringa
riconoscendo interi, float, double o stringhe che
fanno match con una data espressione regolare
Nella sua versione di default i separatori sono
gli spazi bianchi
Si vedano le API per maggiori dettagli
Laboratorio di Programmazione
Luca Tesei
72
Esercizio
●
●
Riscrivere il costruttore della classe Purse in
modo che chieda in input il numero di monete
iniziali
Aggiungere alla classe Purse un metodo che
restituisca il totale in dollari e in penny (100
penny = 1 dollaro) (Suggerimento: usare la
divisione intera e il resto della divisione intera)
Laboratorio di Programmazione
Luca Tesei
73
Esercizio
●
●
●
●
Scrivere una classe
RisolutoreEquazione2Grado
Il costruttore deve chiedere in input i coefficienti
a, b, c dell’equazione
Implementare i due metodi per dare le due
soluzioni:
–
public double getFirstSolution()
–
public double getSecondSolution()
Scrivere una classe test
Laboratorio di Programmazione
Luca Tesei
74
Esercizio
●
●
●
●
●
Scrivere un programma che assista un cassiere
nel dare il resto
Input: sommaDaPagare e sommaRicevuta
La differenza sommaRicevuta –
sommaDaPagare rappresenta il resto da dare
Il resto deve essere corrisposto usando le
seguenti banconote/monete: 1 dollaro, 1
Quarter, 1 Dimes, 1 Nickel, 1 Penny
Il programma deve indicare quante monete di
ogni tipo il cassiere deve dare --continua
Laboratorio di Programmazione
Luca Tesei
75
Esercizio cont’d
●
●
Il programma deve fornire una soluzione che
corrisponda all’erogazione del minimo numero
possibile di banconote/monete
Esempio
Cassiere harry = new Cassiere();
harry.setSommaDaPagare(8.37);
harry.riceve(10);
int dollars = harry.returnDollars(); // Restituisce 1
int quarters = harry.returnQuarters(); // Restituisce 2
int dimes = harry.returnDimes(); // Restituisce 1
int nickels = harry.returnNickels(); // Restituisce 0
int pennies = harry.returnPennies(); // Restituisce 3
Laboratorio di Programmazione
Luca Tesei
76
Esercizio
●
Scrivere un programma che legge un numero intero e
poi stampa le sue cifre, una ad una, in ordine inverso
●
Esempio: se leggo 78349
●
Deve stampare
●
9
●
4
●
3
●
8
●
7
Laboratorio di Programmazione
Luca Tesei
77
Esercizio
●
●
●
Scrivere un programma che calcoli la data della
domenica di Pasqua, che è la prima domenica dopo la
prima luna piena di primavera, di un qualunque anno.
Si usi il seguente algoritmo ideato da Carl Friedrich
Gauss nel 1800:
Sia y l’anno (1800, 2001, ...)
●
Dividi y per 19 ottenendo il resto a. Ignora il quoziente
●
Dividi y per 100 ottenendo il quoziente b e il resto c
●
Continua 
Laboratorio di Programmazione
Luca Tesei
78
Esercizio cont’d
●
●
●
●
●
●
Dividi b per 4 ottenendo quoziente d e resto e
Dividi 8 * b + 13 per 25 ottenendo il quoziente g.
Ignora il resto.
Dividi 19 * a + b - d - g + 15 per 30 ottenendo il
resto h. Ignora il quoziente.
Dividi c per 4 , ottenendo il quoziente j e il resto k
Dividi a + 11 * h per 319, ottenendo il quoziente m.
Ignora il resto
Continua 
Laboratorio di Programmazione
Luca Tesei
79
Esercizio cont’d
●
●
●
●
●
Dividi 2 * e + 2 * j - k - h + m + 32 per 7
ottenendo il resto r. Ignora il quoziente
Dividi h - m + r + 90 per 25, ottenendo il
quoziente n. Ignora il resto
Dividi h - m + r + n + 19 per 32 ottenendo il
resto p. Ignora il quoziente
Pasqua cade il giorno p del mese n
Scrivere una classe Year con metodi
getEasterDay() e getEasterMonth()
Laboratorio di Programmazione
Luca Tesei
80