275 71 296MB
Italian Pages 544 [270] Year 2020
-
Java l Guida completa Variabili, tipi di dato e operatori
l
Operatore unario che inverte tutti i bit
NOT
op1XorOp2 vale 53 in quanto nel risultato saranno a 1 tutti i bit impostati a l esclu-
sivamente in uno dei due operandi. Pertanto, il secondo bit da destra in op1XorOp2 sarà impostato a O in quanto valeva l sia in opl che in op2.
trasformando li O in l e viceversa
--------~~------~~-
Operazione svo ta bit a bit tra due operandi: ogni bit del primo viene compara to con l'analogo bit dei
AND
&
secondo e nel risultato, ne lla medesima posizione vi sarà un bit pari a l solo se entrambi i bit confrontati valgono 1 Operazione svolta bit a bit tra due operandi: ogni bit del primo viene comparato con l'analogo
OR
'
In questo ambito, si annoverano anche le operazioni di shifting che prevedono uno scorrimento dei bit verso destra o sinistra. Non si tratta di una rotazione pertanto i bit che scorrendo vengono esclusi dal dato né ricompaiono all'altra estremità né sono recuperabili in alcun modo. Esistono tre operatori in materia.
Tabella 2.7 - Operatori di shifting. Operatore
b1t del secondo e ne l ri sultato, nella medesima
l
l
Simbolo
Vengono fatti scorrere verso destra tanti bit appartenenti al primo operando quanti ne indica il secondo. Aritmeticamente, l'operazione ha l'effetto di una divisione per due evato al numero che rappresenta il secondo operando. Quindi: 35 » 3 aritmeticamente equivale 3 a 35 l 2 Vengono fatti scorrere verso sinistra tanti bit appartenenti al primo operando quanti ne indica il secondo. Aritmeticamente, l'operazione ha l'effetto di una moltiplicazione per due elevato al numero che rappresenta il secondo operando. In pratica: 35 « 3 aritmeticamente equivale 3 a 35 * 2 Identico al comportamento dello shift a destra ma il risultato verrà trattato come un numero itivo
posizione, vi sarà un bit pari a 1 se almeno uno dei due bit confrontati vale 1 Operazione svolta bit a bit tra due operandi:
Shift a destra
' >>
Shift a sinistra
>>
ogni bit del primo vien e comparato con l'analogo
XOR
bit del secondo e ne l risultato, nella medesima posizione, vi sarà un bit pari a l solo se esclusivamente uno dei due bit confrontati vale 1 in t ap 1=35 . . 'lllb' lnt op2=22; n lnario . Il ln blnar io l nt no tOpi= op1 .
uni ca coli con i
d
. pr~ ett1operatori :
0010 0011 0001 0110
N
Il vale -3 6
-,
int opt Ando 2P-
Opi
&
op 2,·
Il vale 2
int Op10rOp2- Op1 [ Dp2; Il vale 55 int Op1XorOp2= Op1 A Op2 l . ' l va l e 53 Nel comm t' . en l Innestati l • natopt contie . ne codice abb ianno i . . compone 'l ne li valore -36 la c . nserlto l risultati · , l numero 35 Ui co difi ca bi . , . aGP1Andop2 vale 2 e ciò , nna con tutti i bit inv tnana e da ta dalla sequenza che h Unici bit . e venficabile er Ili; destr Impostati a l . osserva ndo la .. • P2valessl Ola non l nellase d d erano irn a cui Codific b' azzerarsi nel . con a posizione a Postati a l in l a lnaria nno t ris ultato finale· a meno uno d . s ra a l tutti i b. ' . e due operandi · lt nelle posizioni in cUI 1
Descrizione
Seguono esempi di utilizzo di tali operatori: int op1=35;
Il in binario 0010 0011 > ; int shiftDxNoSegno= opi >>>
'
d'f h binarie del primo operatore e dei risultati come riportato nei Osservando le co l IC e l' ffetto degli scorrimenti a destra o a sinistra. Si faccia menti si può osservare e d 'l com . , . o aritmetico che tali operazioni assumono. Essen o l seconattenzlone anche al nfless 'f d t è equivalso a una divisione per 4 (2 elevato do operatore pari a 2, uno shl t a es ra
'
DigitaJ LifeStyle*pro
Variabili, tipi di dato e operatori
Java l Guida completa
. . h uadruplicato il primo operando. shift a s1n1stra a q . 0 1 da) e analogamente, t . visti si nora m questo paragrafo (a alla secon ' . . h tutti gli opera on . . eludere si cons1der1 c e . mista con l'operatore d1 assegnazloPer con ' . no di una vers1one , .. . esclusione del NOT) d1spongo . 't metici si potra utd1zzare come pnmo . er gli operatori ari , . . . b'le che sarà destinatana del nsultato: ne. Pertanto, com e avviene P ·,1 valo re custodito nell a stessa vana ' , operan do . . = = =;
• '
Tabella 2.8 - Parole riservate del l abstract
assert
case
catch
continue
defalllt
enum
extends for
float operatori di shifting con assegnazione. > - ,
'
. empi in cui partirem o dal valore 43 conservato in d t Il Concludiamo con una carre a a l es . . . ' . . . via via agendo direttamente SUl suo1 b1t. L evoluzione una vana bile e lo tras 1ormerem 0 . . . . dell'esperimento potrà essere seguita con quanto riportato nel commen ti a lato di ogn1 riga di codice. i nt va l ore=43;
import protected
instanceof new pubi ic
strictfp throw
su per throws
native
voi d
•
Java •
boolean char
break class
do false
double fina l if
goto in t
interface package short
null return switch tra nsient while
volatile
synchronized true
byte const else finally implements long private stati c this try
--[
Il in binario 0010 1011
valore &= 33; valor e l= 10; valore ' = 12 ;
Il risultato 33 , in binario 0010 0001 11 con il r i sultato torniamo a 43, in binario 0010 1011 Il risu l tato 39, in binario 0010 0111
valore «= 3; 1000 valore »= 2,
Il ris ul tato 312 (39 Il ris ultato 78
*
(2 elevato 3 )) , in binario 0001 001 1
(312 l ( 2 elevato 2 ) ), in binario 0100 11 1 0
Come un identificatore: cosa considerare e cosa evitare Negli esempi , abbiamo già fissato al . . d' . .. d tt . . .. cun l nomi 'vanabi1 1. Il programmat ore, come e o, puo scegl1erl111beramente ma dev Più che di nomi di va . b. . . ono comunque essere rispettate alcune regole. na 11t, In questo paragraf 1· .• •• stesse norme si applican o, par lamo d1 1dent1f1catori visto che le o a c assi, metodi enum . . . remo affrontando la Pro . ' erazlon 1e altn costrutti che conoscegrammazlone Orient t l'O Un identificatore in Java . a a ag l ggetti. puo contenere lettere m . . score e dollaro (rispettivame t aluscole, mmuscole, i simboli underziare c n e,- e $) nonché nu · s·1b · on un numero. Pertanto e . . men . ad1però che non può inipossano semb . , spress lonl come a2$ ABC . lt . rare sono tdentificatori val d o _34 per Impro babili che 1no re, un Identificatore non . l l mentre Si mporto non lo è .
.
Oltre a considerare cosa è possibile o meno a livello sintattico, è importante tenere presente che una scelta oculata degli identificatori migliora la leggibilità del codice agli occhi propri e di chiunque altro lo leggerà. Nello specifico, i nomi di variabili dovrebbero essere significativi, indicando perciò il concetto che rappresentano. Se un valore intero, per esempio, è destinato a contenere il numero di vani di un appartamento, dovremmo scegliere un nome simile a numeroVani o vaniAIIoggio. Tra l'altro, in merito a questi ultimi esempi, si consideri che il nome di una variabile: • secondo le convenzioni del linguaggio Java, deve iniziare con una lettera minuscola; • se è frutto della composizione di più parole, queste saranno concatenate convertendo in maiuscolo l'iniziale di ognuna di esse esclusa la prima. Pensiamo a esempi come vaniAIIoggio, numeroStudenti, totaleFatturaOrdine e via dicendo. Questa forma di composizione prende il nome di ca mel case perché la presenza di lettere maiuscole in sequenze di minuscole ricorda la linea tracciata dalle gobbe
1
Java proprio per dare l . puo,essere una parola chi . . • ch e abb . a posslbli,ta al com p l t . ave o nservata del linguaggiO tamo scntto. Pro . l a ore di inter t non possono es POntamo qui di seguito pre are con certezza il codice sere usate co . un elenco d. l . . da agevolare larice ) me Identificatori c· . l paro e ChiaVe d1 Java che rea Molt d' In ordine lf b . ma presto diventeran . l . e l queste lascera a a et ico per righe in modo no amt ll ari t t nno al mom t 'l u te o quasi. en o l lettore ind ifferente
sul dorso di un cammello.
oni
hee
••
Capita che i dati conservati in variabili di un determinato tipo debbano essere passati in altre di tipo diverso. Si può fare? Èsempre possibile ciò? In questo paragrafo, rispon diamo a tali dubbi e introduciamo un operatore che nella vita dei programmatori va usato spesso e bene: l'operatore di cast. Esistono delle conversioni automatiche in Java che possono essere inserite nel codice e vengono direttamente avallate dal compilatore in quanto non rischiano di causare perdite di dati. La tabella che segue ne mostra un elenco.
Digi talLifeStyle*pro
Variabili, tipi di dato e operatori
Java l Guida completa
Pertanto, un'espressione co 2 1213 6 int risul tato=2+ * ;
. guite le operazioni di moltiplicate verranno pnma ese . . Secondo le precedenze espos ' . mente i loro risultati saranno COinvolti solo success1va ) 3 ( 2 / zione (6*2) e divisione l e •
•
in so mme e sottrazioni. .. d'lne di esecuzione inv iolabile, non gara nd e stabd1scano un or Nonostante le prece enz h' ggibil ità pertanto l'uso di parentesi tonde è 1 tiscono per il programmatore una c !ara e d • • • • t Le parentesi tonde assumono prece enza nspetto comunque vivamente conslg 1la o. . . . . t . ra ' prima risolta l'esp re ssiOne alloro mterno e solo sue. . . . a quals1as1 altro opera ore. sa . t ·r · /t to ottenuto verrà coinvolto nel le restanti operaz1on1. Applicando cess1vamen e 1nsu a le parentesi tonde in una determinata posizione alla precedente espressione il risultato
Un aspetto fondamentale che vale la pe . d , na ncor are e che P , t·r· se si fornisce un valore d'· · . • var uo essere u 11zzato solo l IniZia 1IZZazione altrim t'd' . un tipo di dato idoneo. , en ' lventa Impossibile determinare Per esempio, quello che segue costituirebbe errore: var nuovaVariabile; '
E in:~ressa~te anch~ considerare che var non rappresenta una parola riservata equest~ .e'' motivo per CUI ~o n appare nella Tabella 2.8. Conseguenza di ciò è che potremmo utrllzzare questo termme come nome di variabile anche con type inference. Quello che segue, per strano che possa sembrare, funziona : var var=10 ;
non sarà più 10 bensì -16: In questo caso è appena nata nel nostro programma una variabile di nome var, di tipo intero, inizia/izzata a 10.
int risultato=( Zt6)*( 2-12/3); Si consideri comu nque che nei prossimi capitoli conosceremo ulteri ori operatori disponibili ne/lingu aggio Java, anche questi portatori dell e loro priorità che si innesteranno nella "classifica" vi sta in questo paragrafo.
• 1 con
di
var
Nella versione 10 di Java è stata introdotta una modalità particolarmente utile per la dich1araz1oned1 una variab 'l ·i' d. (" . . 'e . uso 'var. IO rappresenta una sorta di deroga a quanto . descntto smora. Si tratta di un identi ficatore che permette d . . senza specificarne il tipo di dato. ' dichiarare una variabile, inizializzata, Per esempio, con: var numero=10 . '
Java creerà unavariabile d.1t' . . utilizzare l' . lpo mtero, Impostata a 10 1 lt . approcc1o classico sp l . . · n a ernallva, avrem mo potuto caso, un mec · . ecl !cando li t1po di · . 1ca1re
,
sora
··
re !polo . d' non espi · 't L Avrem gle 'dati. ICI a. o stesso avremmo potuto mo potuto assegnare un numero n · var numeroConv· on Intero · lrgol a = 1 56 · . oppure un valore bo l o eano·• var valorelogico:true
'
Un altro aspetto fondamentale- anche se a questo punto de/libro può sembrare poco significativo - è che var è utilizzabile solo per variabili locali, ossia quelle che vengono dichiarate all'interno di una coppia di parentesi graffe legate a qualche costrutto sintattico. A proposito di var, esistono altre restrizioni e casistiche da considerare, ma non è ancora il momento di parlarne in quanto nel testo troveremo circostanze più opportune, una volta affrontati gli argomenti giusti.
Riepilogo Per poter programmare serve innanzitutto conservare i dati in variabili. Queste vanno sempre dichiarate prima de/loro utilizzo e dovremo avere l'accortezza di scegliere un tipo di dato adatto e un identificatore corretto e significativo. In Java, esistono otto tipi di dato primitivi per rappresentare le informazioni più basilari: numeri, caratteri e valori logici. Sarà poi la Programmazione Orientata agli Oggetti a insegnarci a costruire agglomerati di informazioni più complessi. Con gli operatori aritmetici possiamo iniziare a svolgere calcoli per risolvere problemi : preleviamo valori dalle variabili, svolgiamo le operazioni necessarie e posizioniamo il risultato nuovamente in una variabile. Esistono anche operatori bitwise che lavorano sui bit: hanno un uso più specifico ma sono comunque molto utili. Le variabili vanno usate correttamente, rispettando i tipi di dato e le loro regole : assegnare valori con i literals previsti, eseguire conversioni eventualmente apponendo l'operatore di cast e tenere in considerazione le priorità.
D igitalLifeStyle*p ro
• re 1
usso
La programmazione non sarebbe altrettanto utile se non permettesse di
decidere
se eseguire un blocco di codice e se
ripeterne l'esecuzione più volte. Queste decisioni vengono
condizioni tramite operatori di confronto e logici. Tale insieme di attività rientra nell'ambito del controllo del flusso di esecuzione e consiste per lo più nell'uso di costrutti condizionali e cicli. prese verificando
Gestire il
diesecu
Gli esempi che abbiamo incontrato nei capitoli precedenti potevano essere considerati "semplici" e questo non solo per le finalità che si prefiggevano o per la limitatezza dei concetti chiamati in causa ma soprattutto perché le righe di codice che li componevano venivano eseguite tutte, in ordine dalla prima all'ultima. In pratica, possiamo affermare che il loro flusso di esecuzione- vale a dire la sequenza di istruzioni che deve essere eseguita dall'avvio al termine del programma- è lineare. Tuttavia, casi simili sono estremamente limitati nella regolare attività del programmatore e ciò perché un software deve poter reagire a eventi e rispondere a st imoli provenienti dall'esterno (input immesso dall'utente, disponibilità di dati da elaborare, eventuali situazioni anomale o di errore e via dicendo).
DigitalLifeStyle*pro
Controllare il flusso di esecuzione
Java l Guida completa
. lica la ver ifica dell a sussistenza di ro ramma lmP . . .
.
. . . h rendano passi eventuali condiZIOni c e . . · et1z1one. · · d' t tti · di istruzioni o la loro np . ratica con due t ipi l cos ru . . . 'l , essere messo In p . d. b un arbitraggio s1m1 e puo . ·t o il costrutto i t che 1n 1ca se un lo eco . d' . ali· vedremo In men • costrutti con IZIOn · . eno nonché il costrutto swi tch ...case e l'apedi codice deve essere eseguito o m •
•
ratore ternano; b't · . . . d'bi chi di codice: in questo am 1o Impareremo a usare cicli per la npet1Z1on e l oc i costrutti whi le e for.
Come abbiamo già sottolineato, la gestione del flusso di esecuzione poggia su Ila verifica di condizioni, attività che viene espl icata per lo più tramite 'uso di operatori di confronto e logici: di questo ci occuperemo nei prossimi paragrafi.
Operatori di confronto Gli operatori mostrati nella tabella seguente permettono di esegui re un confronto tra due operandi e attenerne il risultato che sarà sempre un valore booleano. Tabella 3.1 • Operatori di confronto.
--•
>
Verifica l'uguaglianza tra due operandi Verifica la diversità di due operan di Esem o: 5! =6, risu ltato vero Verifica se il primo operando ha un valore maggiore del secon do
5 · ' System .out.pr intln (" 4>5 = "+confronto );
Il secondo es empio : utilizzo del simbolo di maggiore con fronto = 4>=4; System .out.println ( "4 >=4 = "+confronto );
Esem io: 5>6, risul tato fa lso Verifica se il primo operan do ha un valore minore de l seco ndo
confronto = (op1 == (2*2 )) ; System .out . println ( "(1614) == (2*2 )
=ftne ) { System.out. pr i ntln (contatore ); Il ERRORE! Per passare da 29 a 15 il contatore va decrementato contatore++;
int fine=29 ;
•
whi l e(contatore =flne non diverrà falsa e il ciclo non si interromperà mai.
ì nt contator e=29; i nt flne=15 ; while (contatore