Menu


Trascrizione diapositive

1. Operatori e gestione del flusso di esecuzione

  • Complessità: MEDIA.


2. Operatore di assegnazione

  • Si tratta dell’operatore uguale «=» che viene utilizzato per assegnare un determinato valore ad una variabile. Questo operatore è spesso presente anche in molti linguaggi di programmazione evoluti diversi da Java. Ecco vari esempi di assegnazione di valore ad una variabile:

    int numero = 1;
    char lettera = 'a';
    boolean veroOFalso = true;


3. Operatori aritmetici

  • Gli operatori aritmetici permettono di effettuare operazioni matematiche tra numeri e/o variabili. Di seguito una tabella esplicativa:

Descrizione

Operatore

Addizione

+

Sottrazione

-

Moltiplicazione

*

Divisione

/

Modulo

%

Quando viene svolta una operazione in modulo «%», in realtà viene effettuata una divisione tra operandi, il risultato restituito coincide con il resto della divisione stessa.


4. Operatori aritmetici di assegnazione

  • Gli operatori aritmetici di assegnazione permettono di effettuare un operazione aritmetica assegnando il risultato ad una variabile con una sintassi molto più compatta. Ecco l’elenco completo degli operatori (nella prossima slide la guida su come utilizzarli):

Descrizione

Operatore

Addizione ed assegnazione

+=

Sottrazione ed assegnazione

-=

Moltiplicazione ed assegnazione

*=

Divisione ed assegnazione

/=

Modulo ed assegnazione

%=



5. Operatori aritmetici di assegnazione

  • L’utilizzo di un operatore aritmetico di assegnazione è abbastanza semplice, ad esempio se abbiamo:

int numero = 1;

e decidiamo di effettuare con l’utilizzo di questa variabile una determinata somma, assegnando il risultato alla stessa variabile «numero», possiamo procedere con la seguente classica sintassi:

numero = numero + 5; // La variabile “numero” conterrà il valore 6

oppure possiamo utilizzare un operatore aritmetico di assegnazione in questo modo:

numero += 5; // La variabile “numero” conterrà il valore 6

  • Ovviamente questa tecnica è valida anche per la sottrazione, moltiplicazione, divisione e modulo.


6. Operatori di incremento e decremento

  • Ecco un elenco completo degli operatori di incremento e decremento:

Descrizione

Esempio

Pre-incremento di un’unità

++i

Pre-decremento di un’unità

--i

Post-incremento di un’unità

i++

Post-decremento di un’unità

i--

  • Notare la differenza tra pre e post incremento/decremento:
Differenza tra pre e post incremento/decremento


7. Operatore bitwise

  • Ecco un elenco esaustivo di tutti gli operatori bitwise, nelle prossime diapositive la guida su come utilizzarli:

Descrizione

Operatore

NOT

~

AND

&

OR

|

XOR

^

Shift a sinistra

<< 

Shift a destra

>> 

Shift a destra senza segno

>>> 



8. Operatore NOT

  • Gli operatori bitwise permettono di agire direttamente su i bit di una determinata variabile, l’utilizzo di questi operatori in Java è rarissimo; ad ogni modo si cercherà di comprenderne passo-passo le funzionalità, in modo tale da conoscere un aspetto che per molti programmatori (anche esperti) è oscuro.
  • L’operatore di più facile apprendimento è senza alcun dubbio quello chiamato NOT «~», si tratta di un operatore unario in quanto agisce su ogni singolo bit, ad esempio una variabile di tipo byte (8 bit) che rappresenta il numero uno «1», sarà immagazzinata con il valore «00000001», se applichiamo NOT a questa variabile otterremo «11111110»:
NOT


9. Operatore AND

  • L’operatore AND agisce a differenza dell’operatore NOT anche su coppie di operandi di tipo boolean, vediamo come funziona:

primoOperando

secondoOperando

primoOperando​AND​secondoOperando

false

false

false

false

true

false

true

false

false

true

true

true

  • Esempio in codice:
AND


10. Operatore OR

  • Anche l’operatore OR agisce su coppie di operandi di tipo boolean, vediamo come funziona:

primoOperando

secondoOperando

primoOperando​OR​secondoOperando

false

false

false

false

true

true

true

false

true

true

true

true

  • Esempio in codice:
OR


11. Operatore XOR

  • L’operatore XOR come gli ultimi due operatori menzionati, agisce anche su coppie di operandi di tipo boolean, vediamo come funziona:

primoOperando

secondoOperando

primoOperando​XOR​secondoOperando

false

false

false

false

true

true

true

false

true

true

true

false

  • Esempio in codice:
XOR


12. Operatore di Shift

  • Gli operatori di Shift provocano lo scorrimento di un certo numero di bit immagazzinati solitamente in una determinata variabile, l’utilizzo pratico dello scorrimento si applica chiaramente a valori di tipo non logico-booleano (perché formati da un solo bit).
  • Il numero dei bit da scorrere è rappresentato dal valore a destra dell’operatore. Esempio:
    Shift a destra
  • Dopo lo scorrimento i bit che si trovano al di fuori della rappresentazione binaria del numero vengono rimossi, e vengono rimpiazzati da valori che possono essere «0» oppure «1» a seconda del caso.
  • Lo scorrimento a sinistra provoca un riempimento con valori «0» dei bit lasciati vuoti sulla destra.
  • Anche lo scorrimento a destra senza segno provoca un riempimento con valori «0» dei bit lasciati vuoti sulla sinistra.
  • Lo scorrimento a destra, invece, provoca un riempimento con valori «0» o «1» dei bit lasciati vuoti sulla sinistra, a secondo del primo bit di sinistra, se esso è pari a «0», le posizioni vuote verranno rimpiazzate con bit pari a «0», mentre se è pari a «1», verranno rimpiazzate con bit pari a «1».


13. Operatore bitwise di assegnazione

  • Ecco un elenco esaustivo di tutti gli operatori bitwise di assegnazione, l’utilizzo pratico è identico a quello utilizzato per l’operatore aritmetico di assegnazione:

Descrizione

Operatore

AND e assegnazione

&=

OR e assegnazione

|=

XOR e assegnazione

^=

Shift a sinistra e assegnazione

<<=

Shift a destra e assegnazione

>>=

Shift a destra senza segno e assegnazione

>>>=



14. Operatori logico-booleani

  • Gli operatori logico-booleani possono operare solo con operandi di tipo booleano, il risultato di un operazione basata su tali operatori è di tipo boolean. Ecco un elenco esaustivo di tutti gli operatori:

Descrizione

Operatore

NOT logico

!

AND logico

&

OR logico

|

XOR logico

^

Short circuit AND

&&

Short circuit OR

||

È facile trovare punti di contatto con la lista degli operatori bitwise.


15. Differenza tra NOT logico e NOT bitwise

  • Trovati i punti di contatto con la precedente lista degli operatori bitwise, è bene specificare le varie differenze.
  • Un NOT di tipo logico «!» e un NOT di tipo bitwise «~» agiscono a livello concettuale allo stesso identico modo, ma a livello applicativo sono assai differenti, infatti l’operatore NOT logico agisce solo su variabili dichiarate di tipo boolean, mentre l’operatore NOT bitwise agisce su tutti i tipi interi di variabile tranne boolean, quindi è consentito scrivere:

[Codice] NOT Logico
  • Mentre non è consentito scrivere:
[Codice] Errore
  • Quindi è corretto utilizzare l’operatore NOT bitwise su tipi interi, esempio:
[Codice] NOT bitwise


16. Operatori short circuit

  • Gli operatori di corto circuito permettono di aumentare le performance di una determinata applicazione, vediamo come attraverso un esempio pratico:

boolean flag = ( (a != 0) && (b > 10) );

  • In questo caso affinché la variabile «flag» sia pari a «true», è necessario che entrambi gli operandi dell’AND restituiscano «true», ma se il primo operando è in partenza falso non ha senso controllare anche il secondo operando.
  • Quest’operatore, quindi, a differenza del suo corrispettivo tradizionale «&», permette di evitare il secondo controllo in caso di fallimento del primo.
  • Stessa logica per l’operatore di short circuit OR «||», in quanto nel caso il primo operando risultasse «true», viene convalidata l’intera espressione senza nessun superfluo controllo.


17. Operatori logico-booleani di assegnazione

  • Ecco un elenco esaustivo di tutti gli operatori logico-booleani di assegnazione, l’utilizzo pratico è identico a quello utilizzato per l’operatore aritmetico di assegnazione:

Descrizione

Operatore

AND e assegnazione

&=

OR e assegnazione

|=

XOR e assegnazione

^=



18. Operatori relazionali o di confronto

  • Gli operatori relazionali e di confronto sono molto importanti nella gestione del flusso di esecuzione di un programma. Il valore restituito è sempre di tipo boolean, ovvero «true» o «false».

Operatore

Simbolo

Applicabilità

Uguale a

==

Tutti i tipi

Diverso da

!=

Tutti i tipi

Maggiore

Solo tipi numerici

Minore

Solo tipi numerici

Maggiore o uguale

>=

Solo tipi numerici

Minore o uguale

<=

Solo tipi numerici



19. Concatenazione di stringhe

  • L’operatore «+», oltre ad essere un operatore aritmetico permette anche di concatenare stringhe. Ad esempio:

String nome = “Paolo ”;
String cognome = “Rossi”;
String nomeCompleto = “Sig. “ + nome + cognome;


  • La variabile stringa «nomeCompleto» contiene «Sig. Paolo Rossi».
  • Se usiamo l’operatore «+» per sommare un qualsiasi tipo di dato con una stringa, il tipo di dato sarà convertito in stringa e ciò spesso può risultare utile.


20. Priorità degli operatori

  • Non è necessario conoscere a memoria tutte le priorità per programmare. Nell’incertezza, si possono sempre utilizzare le parentesi tonde così come faremmo nell’aritmetica tradizionale.

Separatori

. [] () ; ,

Da sinistra a destra

++ -- + - ~ ! (tipi di dati)

Da sinistra a destra

* / %

Da sinistra a destra

+ -

Da sinistra a destra

<< >> >>>

Da sinistra a destra

< > <= >= instanceof

Da sinistra a destra

== !=

Da sinistra a destra

&

Da sinistra a destra

^

Da sinistra a destra

|

Da sinistra a destra

&&

Da sinistra a destra

||

Da destra a sinistra

?:

Da destra a sinistra

= *= /= %= += -= <<= >>= >>>= &= ^= |=



21. Gestione del flusso di esecuzione

  • In Java il flusso di esecuzione può essere gestito attraverso due strutture di controllo sul dato, che si possono distinguere essenzialmente in:

  • - Strutture di controllo decisionali
  • - Strutture di controllo iterative

  • Le strutture di controllo decisionali permettono nella fase di esecuzione, una scelta tra l’esecuzione di istruzioni diverse a seconda della verifica di una specificata condizione.
  • Le strutture di controllo iterative permettono in fase di esecuzione, di decidere il numero di esecuzioni di una determinata istruzione.


22. Gestione del flusso di esecuzione

  • Java utilizza le seguenti strutture di controllo decisionali:

  • - Costrutto «if-else»
  • - Costrutto «switch»
  • - Operatore ternario

  • Mentre le strutture di controllo iterative sono:

  • - Ciclo «while»
  • - Ciclo «do-while»
  • - Ciclo «for»
  • - Ciclo «for migliorato»


23. Istruzione if-else

  • L’istruzione «if-else» può avere due forme: con o senza «else». Le due forme sono:

if (espressione) {
// Codice da eseguire
}

  • Oppure con «else»:

if (espressione) {
// Codice da eseguire
} else {
// Codice da eseguire
}

  • Ma si possono comporre costrutti anche nel seguente modo:

if (espressione) {
// Codice da eseguire
} else if (espressione) {
// Codice da eseguire
} else {
// Codice da eseguire
}


24. Istruzione if-else

  • Come abbiamo visto nella precedente slide all’interno delle parentesi tonde riguardanti l’istruzione «if» e «else if» deve essere inserita un’espressione, essa può restituire valore vero o falso.
  • Mentre il codice da eseguire può essere formato da una semplice istruzione terminata da un punto e virgola o un’istruzione composta, cioè un insieme di istruzioni racchiuse tra parentesi graffe. Si noti che l’istruzione può essere un altro «if» e in tal caso si ottengono delle istruzioni «if annidate».
  • Ricordiamo che per eseguire le istruzioni all’interno di «if» è necessario che l’espressione contenuta tra parentesi restituisca valore vero, se l’espressione del primo «if» e di tutti gli eventuali restanti «else if» restituiscono valore falso, verrà eseguito il codice contenuto dentro «else» (sempre se esso esiste).


25. Esempio di istruzione if-else

26. Istruzione switch

  • L’istruzione «switch» effettua la selezione tra diversi blocchi di codice, in dipendenza dal valore di un’espressione intera o di una stringa. La sintassi dell’istruzione «switch» è la seguente:

switch (selettore) {
case valore1: {
// Codice da eseguire
}
break;


case valore2: {
// Codice da eseguire
}
break;


default: {
// Codice da eseguire
}
}


27. Istruzione switch

  • Il selettore è una stringa o un valore intero.
    L’istruzione «switch» confronta il risultato del selettore con i valori di ciascun ramo «case».
  • Se trova una corrispondenza, viene eseguita l’istruzione (semplice o composta) associata al «case», altrimenti viene eseguita l’istruzione del ramo «default» (sempre se esso esiste).
  • Si può notare come ogni «case» termini con un’istruzione «break» che consente di saltare alla fine del corpo dell’istruzione «switch». Il «break» è opzionale, se manca viene eseguito il «case» successivo.


28. Esempio di switch

29. Operatore ternario

  • L’operatore ternario può essere una valida alternativa all’istruzione «if», esso è anche detto operatore condizionale perché regola il flusso di esecuzione a seguito di una determinata condizione. Ecco la sintassi:

variabile = (espressione) ? valore1 : valore2;

  • Se il valore dell’espressione è vero si assegna alla variabile il «valore1», altrimenti si assegna alla variabile il «valore2».


30. Esempio di operatore ternario

31. Parole chiave break e continue

  • Le parole chiave «break» e «continue» servono per controllare il flusso all’interno del corpo di un ciclo.
  • L’istruzione «break» consente di interrompere l’esecuzione del ciclo, passando il controllo all’istruzione successiva al ciclo.
  • L’istruzione «continue» consente di ritornare anticipatamente il controllo all’inizio del ciclo, interrompendo l’esecuzione dell’iterazione corrente.


32. Istruzione while

  • L’istruzione «while» permette di ripetere determinate istruzioni, finché il valore dell’espressione non diventa falso. La sintassi del ciclo «while» è la seguente:

while (espressione) {
// Codice da eseguire
}

  • L’espressione è valutata una volta all’inizio del ciclo, e viene rivalutata a ciascuna iterazione del ciclo.


33. Esempio di while

34. Istruzione do-while

  • La sintassi del «do-while» è la seguente:

do {
// Codice da eseguire
} while (espressione);

  • Il «do-while» differisce dal «while» in quanto il codice viene eseguito sempre almeno una volta, anche se l’espressione da valutare all’inizio è falsa.
  • Mentre nell’istruzione «while», se l’espressione condizionale all’inizio del ciclo è falsa, il codice non viene mai eseguito.


35. Esempio di do-while

36. Istruzione for

  • In un ciclo «for» l’inizializzazione delle variabili del ciclo viene eseguita alla prima iterazione, viene poi verificata la condizione di uscita e alla fine di ciascuna iterazione, vengono aggiornate le variabili del ciclo. La sintassi dell’istruzione «for» è la seguente:

for (inizializzazione; espressione; iterazione) {
// Codice da eseguire
}

  • L’inizializzazione, l’espressione e l’iterazione possono essere vuote.
  • Il codice di inizializzazione viene eseguito una sola volta, all’inizio del ciclo. L’espressione è verificata prima di ogni iterazione (se all’inizio è falsa, il codice non viene mai eseguito).
  • Alla fine di ogni ciclo vengono eseguite le istruzioni di iterazione.


37. Esempio di for

38. Istruzione for migliorato

  • Il ciclo «for migliorato» non è più potente di un ciclo «for» semplice, ma può sostituirlo in alcuni casi.
  • In altri linguaggi di programmazione diversi da Java il ciclo «for migliorato» viene chiamato «foreach» (in italiano «per ogni»), quest’ultimo nome è effettivamente il più appropriato per descrivere questa istruzione. Ecco la sintassi:

for (variabile_temporanea : oggetto_iterabile) {
// Codice da eseguire
}


39. Istruzione for migliorato

  • Per «oggetto_iterabile» si intende un array (o un qualsiasi altro oggetto su cui è possibile iterare).
  • Invece per «variabile_temporanea» si intende una variabile a cui, durante l’esecuzione del ciclo, verrà assegnato il valore dell’i-esimo elemento dell’«oggetto_iterabile» all’i-esima iterazione.
  • In pratica, «variabile_temporanea» rappresenta all’interno del blocco di codice del ciclo «for migliorato» un elemento dell’«oggetto_iterabile».


40. Istruzione for migliorato

  • Di seguito un esempio pratico necessario per fugare ogni eventuale dubbio sul ciclo «for migliorato»:

int [] arr = {1,2,3,4,5,6,7,8,9};
for (int tmp : arr) {
System.out.println(tmp);
}

In questo esempio vengono stampati a video tutti gli elementi dell’array.

  • Notare che questa volta non esiste un espressione booleana che provoca l’uscita dal ciclo, questo perché bisogna utilizzare il ciclo «for migliorato» solo e soltanto se abbiamo intenzione di iterare su tutti gli elementi dell’oggetto iterabile.