OBIETTIVI DELLA LEZIONE
In questa lezione in laboratorio vedremo alcuni dettagli di Java che non avevamo ancora affrontato. Inoltre completeremo e discuteremo eventuali esercizi rimasti irrisolti dalle scorse esercitazioni.
Per la preparazione, potete scaricare un file che contiene 20 domande di livello simile a quelle che troverete all'esame. Le risposte sono contenute in questo secondo file.
Spesso un programma contiene errori "run-time" (cioè, vi ricordo, il codice viene compilato correttamente ma poi in esecuzione non fa quello che avremmo voluto) e non è detto sia facile individuarli. Una tecnica utilizzata per localizzare errori si chiama Debug (togliere i bugs, cioè gli errori). Fare il debug di un file consiste nell'eseguire passo per passo le istruzioni del nostro codice ed ad ogni istante poter rilevare cosa contengono le variabili che stiamo manipolando.
Vediamo quali sono i passi che servono per debuggare un file con Eclipse.
Per prima cosa lanciamo Eclipse e creiamo un progetto che contenga il file Java Lune.java che avevevamo già visto durante la lezione 2.
import java.io.*; class Lune { public static void main(String[] args) throws IOException { InputStreamReader flussoTesto = new InputStreamReader(System.in); BufferedReader bufferTastiera = new BufferedReader(flussoTesto); String lineaLetta; System.out.print("Quanti anni hai? "); lineaLetta = bufferTastiera.readLine(); int anni = Integer.parseInt(lineaLetta); System.out.print("In che mese sei nato (numero)? "); lineaLetta = bufferTastiera.readLine(); short mesi = Short.parseShort(lineaLetta); short numeroLune = (short)(12*anni + mesi); System.out.println("Durante la tua vita, hai visto " + numeroLune + " lune."); } }
Il nostro obbiettivo è quello di sapere che cosa contenga la variabile numeroLune prima che venga eseguita la riga di codice numero 18 (System.out.println("Durante la tua vita, hai visto " + ...). Vorremmo in sostanza interrompere l'esecuzione del codice ad un certo punto o poterlo eseguire "riga per riga".
Per farlo dobbiamo:
Vi suggerisco di esplorare il valore delle variabili, in particolare per gli oggetti come lineaLetta. È molto utile perché vi aiuta a comprendere la struttura degli oggetti Java.
Per proseguire l'esecuzione "riga per riga" basta selezionare "Step Over" (o premere F6) o "Step Into" (o premere F5) dal menù "Run". Il secondo a differenza del primo, permette di seguire l'evoluzione del codice anche quando vengono chiamati dei metodi. Se invece siamo soddisfatti con il debug, possiamo continuare l'esecuzione normalmente con "Resume " sempre dal menù "Run" (o premere F8).
Notate che nel programma Lune.java per poter utilizzare la console per ottenere l'input dall'utente abbiamo:
InputStreamReader flussoTesto = new InputStreamReader(System.in);
BufferedReader bufferTastiera = new BufferedReader(flussoTesto);
lineaLetta = bufferTastiera.readLine();
public static void main(String[] args) throws IOException {
Notate che le operazioni svolte per ottenere l'input da tastiera sono molto simili a quanto fatto nel caso di lettura (e scrittura) di un file. Che fatica rispetto a scanf() del C! Esiste un modo più semplice? A partire da Java 1.5, sì. Vediamolo con un esempio.
import java.util.*; class LuneScanner { public static void main(String[] args) { Scanner tastiera = new Scanner(System.in); System.out.print("Quanti anni hai? "); int anni = tastiera.nextInt(); System.out.print("In che mese sei nato (numero)? "); short mesi = tastiera.nextShort(); short numeroLune = (short)(12*anni + mesi); System.out.println("Durante la tua vita, hai visto " + numeroLune + " lune."); } }
Rivediamo i passi seguiti:
Scanner tastiera = new Scanner(System.in);
int anni = tastiera.nextInt();
short mesi = tastiera.nextShort();
La classe Scanner contiene anche altri metodi utili che vi invito a verificare con il manuale. Ad esempio: nextDouble(), nextLine() o next() che restituiscono il successivo/a double, linea e parola rispettivamente.
Nei vari programma che abbiamo sviluppato durante il corso ci siamo spesso imbattuti nella necessità di stampare a monitor dei double. Di certo non è stato piacevole vedere stampate tutte le cifre decimali. La formattazione dei numeri è sempre stata possibile in Java, ma è divenuta ancora più semplice a partire da Java 1.5.
J2SE 5.0 ha aggiunto il metodo printf(), identico all'equivalente C, alla classe PrintStream. È quindi possibile applicare il metodo all'oggetto System.out. Vediamo un esempio:
double raggio=2.0; // Calcolo l'area del cerchio double areaCerchio = Math.pow(raggio,2)*Math.PI; // stampo l'area del cerchio System.out.println(areaCerchio); // 12.566370614359172 ... troppi decimali! // utilizzo invece printf System.out.printf("%7.2f\n", areaCerchio); // 12.57 ... molto meglio!
Il metodo funziona in modo molto simile alla funzione C. Vi ricordo che si utilizza fornendo una stringa che indica la formattazione che si desidera ("format string"). Nell'esempio abbiamo indicato che la variabile fornita deve essere stampata come un numero in virgola mobile (%f) e deve occupare a monitor l'equivalente di 7 caratteri di cui 2 dopo la virgola (7.2). Inoltre abbiamo utilizzato una sequenza di escape (\n) per andare a capo. Vi invito a consultare il manuale per maggiori informazioni sui singoli tag.
E per formattare l'output quando si utilizzano metodi della classe JOptionPane? È possibile utilizzare il metodo static String.format() che funziona in modo molto simile alla funzione C sprintf(). Ad esempio:
double raggio=2.0; // Calcolo l'area del cerchio double areaCerchio = Math.pow(raggio,2)*Math.PI; // stampo l'area del cerchio JOptionPane.showMessageDialog(null, "L'area del cerchio è" + String.format("%7.2f\n", areaCerchio) ); System.exit(0);
Esercizio 1 [Soluzione]
Costruire la classe CercaNumeriPrimi che elenchi i numeri primi minori di un dato numero fornito dall’utente.
Suggerimento: utilizzate un oggetto di tipo Vector in cui inserire di volta in volta i numeri primi trovati.
Vi ricordo che 1 non è un numero primo e che un numero è primo se è divisibile solo per 1 e per se stesso. Commentate opportunamente il codice con commenti Javadoc.
Esercizi per gli studenti del corso di Laboratorio di Programmazione ad Oggetti
Un file HTML è solo un file di testo ed in Java possiamo creare e modificare dei file di testo. Perché non scrivere un programma che crei automaticamente delle pagine HTML? E' utilissimo sopratutto per strutture ripetitive come le tabelle. Una breve guida ai TAG HTML la trovate all’indirizzo: http://werbach.com/barebones/barebones.html.
Provate a svolgere gli esercizi 3 e 4 della lezione 14 e l'esercizio 3 della lezione 16. Ne vedremo le correzioni nella prossima esercitazione comune. Potete comunque inviarmi i dubbi o le vostre soluzioni per email o fissare un appuntamente per parlarne a ricevimento.
©2008 Roberto Sassi