Si dica quale (o quali) fra le seguenti affermazioni sono errate:
switch/case è più potente dell'if/else
(ossia, qualsiasi istruzione if/else può essere riscritta
usando solo lo switch/case, e non usando l'if/else).char rappresenta parole.String non è uno degli 8 tipi predefiniti del Java.do/while può essere
sempre riscritto eliminando i do/while e sostituendoli con
while (e modificando opportunamente il programma). while può essere
sempre riscritto eliminando i while e sostituendoli con do/while
(e modificando opportunamente il programma).a contiene cento elementi, a[100]
indica l'ultimo elemento.System.out.println(10/4) visualizza 2.5.if (x>y) then a = 1; else a =
2; non si può scrivere con l'istruzione switch/case.
È vero invece il contrario: qualsiasi switch può
essere scritto, talvolta in modo meno elegante, in una serie di if.boolean, byte, char, double,
float, int, long, short.a[99].10 e 4 sono letterali
di tipo int e quindi Java esegue la divisione intera. Verrà
visualizzato 2. Si completi il metodo m seguente (intestazione e corpo) che,
dato un array a di boolean come parametro, assegna
true agli indici multipli di 3 e false agli altri.
public static void m( a) {
}
Il parametro a è un array, quindi l'intestazione del metodo
sarà completata con il tipo che corrisponde all'array di boolean,
cioè boolean[].
Dobbiamo assagnare un valore a tutti gli indici di un array, quindi iniziamo
con un ciclo:
for (int i = 0; i<a.length; i++) .........
L'istruzione for farà variare l'indice i da
zero fino alla lunghezza dell'array a meno 1, quindi anche for
(int i = 0; i <= a.length-1; i++) va bene come soluzione.
Dentro il ciclo dobbiamo assegnare un valore ad ogni elemento dell'array:
for (int i = 0; i<a.length; i++) ... a[i] = ... ...
Se l'indice i è un multiplo di 3, e quindi se il resto
della divisione di i per 3 è uguale a zero (i%3 ==
0), assegneremo ad a[i] il valore true, altrimenti
false. Verrebbe da scrivere
if (i%3 == 0) a[i] = true; else a[i] = false;
però questo modo di scrivere, nonostante premetta di ottenere il risultato
corretto, non è elegante e nemmeno efficiente. Il modo migliore di assegnare
ad a[i] il valore true quando i è
multiplo di 3, è quello di notare che l'espressione (i%3 == 0)
vale true quando i è multiplo di 3 e false
altrimenti e quindi se scriviamo semplicemente a[i] = (i%3 == 0);
faremo in modo che in a[i] venga memorizzato il risultato dell'espressione
(i%3 == 0), cioè proprio quello che chiede l'esercizio.
Il codice completo sarà quindi:
public static void m(boolean[] a) {
for (int i = 0; i<a.length; i++)
a[i] = (i%3 == 0);
}
Si supponga di avere definito in una classe Esame i 2 metodi:
public static double radice2(double x)public static double radice3(double x)che calcolano rispettivamente la radice quadrata e la radice cubica dell'argomento.
Si ipotizzi di essere sempre all'interno della classe Esame (ad
esempio, nel main) e di aver dichiarato le variabili a, b
e c di tipo double. Si scriva l'istruzione che assegna
ad a la radice quadrata della radice cubica della somma di b
e c.
L'esercizio chiede di scrivere una sola istruzione che deve
assegnare ad a (a = ...;) la radice quadrata (radice2(...))
della radice cubica (radice3(...)) della somma di b
e c.
radice2 e radice3 sono metodi di classe, ma visto
che siamo all'interno della stessa classe possiamo chiamarli senza premettere
Esame..
La radice cubica della somma di b e c si ottiene con
radice3(b+c). Il risultato di questa espressione è di tipo
double, come si può capire dall'intestazione del metodo
(...double radice3(...), e quindi può essere passato come
parametro al metodo radice2.
L'istruzione completa è la seguente:
a = radice2(radice3(b+c));
La classe Numero è stata definita nel modo seguente:
class Numero {
private double valore;
public Numero(double x) {
valore = x;
}
public static double meta(Numero n) {
return n.valore / 2;
}
public double doppio() {
return valore * 2;
}
}
Numero
n e poi assegnare a x, e y rispettivamente
la metà di n e il doppio di n.
class UsaNumero {
public static void main(String[] args) {
double x,y;
Numero n = new Numero(10.0);
...
System.out.println(x);
...
System.out.println(y);
}
}
Si riportino nei riquadri seguenti le due istruzioni mancanti (indicate
dai puntini):
Numero (si faccia attenzione:
uno dei due metodi è d'istanza, l'altro è di classe...) x il doppio della metà di n. meta è un metodo di classe che prende
come parametro un oggetto di tipo Numero e restituisce un
valore di tipo double. La variabile x è
di tipo double e quindi, visto che il tipo corrisponde, possiamo
assegnarle il risultato della chiamata al metodo meta. Visto
che il metodo è di classe, per invocarlo occorre premettere il
nome della classe in cui è definito (notate che a differenza dell'esercizio
prececente, ora il codice non sta nella stessa classe in cui sono definiti
i metodi).x = Numero.meta(n);
doppio è d'istanza, quindi per invocarlo
occorre premettere l'istanza a cui vogliamo mandare il messaggio. Visto
che vogliamo il doppio di n scriveremo n.doppio().
Il tipo restituito da doppio è double
e quindi possiamo correttamente assegnare il risultato alla variabile
y che è del tipo corretto.y = n.doppio();
n è
uguale a n e quindi basta assegnare ad x n.
Il ragionamento sarebbe giusto, purtroppo però scrivere x = n;
non è corretto dal punto di vista sintattico ed il compilatore darebbe
errore. Infatti il tipo di x è double, mentre
quello di n è Numero e questi due tipi non
possono essere assegnati l'uno all'altro! Al massimo, per rispettare il ragionamento
ed i tipi si sarebbe potuto scrivere (sbagliando anche in questo caso)
x = n.valore; facendo cioè riferimento alla variabile
di n che contiene il valore vero ed ha il tipo corretto. Purtroppo
anche in questo caso l'istruzione è sbagliata perché valore
è private.Numero:
x = Numero.meta(n).doppio(); (o l'equivalente x
= (Numero.meta(n)).doppio();) è sbagliato perché
non si può invocare il metodo di istanza doppio sul
risultato di Numero.meta(n). Sarebbe come cercare di mandare
il messaggio doppio invece che ad una classe ad un numero
double, infatti il risultato di Numero.meta(n)
è un double. Questa soluzione sarebbe stata corretta
solo se il metodo meta fosse stato dichiarato public
static Numero meta(Numero n). In questo caso però la soluzione
del punto precendete non sarebbe stata più valida. x = Numero.meta(n.doppio()); è sbagliata anch'essa
perché n.doppio() restituisce un double
che non può essere passato come parametro al metodo meta
che invece vuole un oggetto di tipo Numero.x = n.doppio()/2;
Si vuole visualizzare un "trapezio rettangolo" di asterischi, ossia:
*** **** ***** ****** ******* ********
Per farlo viene definito il metodo trapezio seguente.
public static void trapezio() {
for (int i = 1; i <= 6; i++) {
for (int ... )
System.out.print('*');
System.out.println();
}
}
Si completi l'intestazione del secondo ciclo for nel metodo
(si riporti l'intestazione completa qui sotto).
Il ciclo for esterno (quello con parametro i) determina
le righe, infatti l'istruzione System.out.println(), che fa andare
a capo, è interna al solo for esterno.
Il ciclo interno determina il numero di asterischi su una riga. Notate che questo
numero è diverso per ogni riga ed in particolare aumenta di uno ad ogni
riga. Questa osservazione ci permette di capire che nell'intestazione del secondo
for dovrà comparire da qualche parte i, perché
è l'unica cosa che cambia ad ogni riga. In particolare
e quindi
for interno dovrebbe essere for (int j
= 1; j <= (2+1); j++)for interno dovrebbe essere for (int j
= 1; j <= (2+2); j++)for interno dovrebbe essere for (int j
= 1; j <= (2+3); j++)La soluzione sarà:
for (int j = 1; j <= (2+i); j++)
Notate che se non compare i nell'intestazione del secondo ciclo,
questo verrà eseguito sempre lo stesso numero di volte e quindi verrà
visualizzato un rettangolo e non un trapezio.

Paolo Coppola