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.