Sezione 1.3
Operatori. |
||
Una volta appreso dell'esistenza delle variabili e delle costanti possiamo iniziare ad operare con esse. A questo scopo il C++ fornisce degli operatori, che nel nostro linguaggio sono un insieme di parole chiave e simboli speciali. E' importante conoscerli perché essi sono la base del linguaggio C++.
Non è necessario inparare a memoria tutto il contenuto di questa sezione. La maggior parte dei dettagli sono riportati per poterli consultare in seguito qualora se ne abbia bisogno.
a = 5;assegna il valore intero 5 alla variabile a . La parte alla sinistra dell'operatore = è nota come lvalue (left value) e la parte destra rvalue (right value). lvalue deve essere sempre una variabile mentre la parte destra può essere una costante, una variabile, il risultato di una operazione o una qualsiasi combinazione di essi.
Occorre notare che l'operatore di assegnamento opera sempre da destra verso sinistra e non nel senso inverso.
a = b;assegna alla variabile a (lvalue) il valore della variabile b (rvalue) indipendentemente dal valore che era precedentemente memorizzato nella variabile a . Possiamo pensare l'lvalue di a come l'indirizzo della zona di memoria riservata per memorizzare il valore di a mentre l'rvalue di b lo dobbiamo pensare come il valore memorizzato nella zona di memoria riservata per memorizzare il valore di b. Notiamo inoltre che noi stiamo soltanto assegnando ad a il valore di b e che una modifica successiva di b non cambia il nuovo valore di a.
Ad esempio, il seguente codice (in cui è evidenziata in verde come commento l'evoluzione del contenuto delle variabili):
otteniamo alla fine che il valore contenuto in a è 4 e quello contenuto in b è 7. L'ultima modifica di b non ha modificato a, benché appena prima avessimo scritto a = b.int a, b; // a:? b:? a = 10; // a:10 b:? b = 4; // a:10 b:4 a = b; // a:4 b:4 b = 7; // a:4 b:7
Una caratteristica dell'operatore di assegnamento presente in C++ ma non in altri linguaggi di programmazione è che un assegnamento si può usare come rvalue (o parte di un rvalue ) in un altro assegnamento. Ad esempio:
a = 2 + (b = 5);è equivalente a:
b = 5;ossia: prima assegna 5 alla variabile b e poi assegna ad a il valore 2 più il risultato del precedente assegnamento a b ( 5 appunto), ottenendo 7 come valore finale di a. Quindi, anche la seguente espressione è valida in C++:
a = 2 + b;
a = b = c = 5;assegna 5 a tutte e tre le variabili a, b e c.
Gli operatori di somma, differenza, moltiplicazione e divisione denotano le usuali quattro operazioni numeriche. L'operatore di modulo fornisce il resto della divisione di due numeri interi. Ad esempio, se scriviamo a = 11 % 3;, viene assegnato alla variabile a il valore 2 in quanto 2 è proprio il resto che si ottiene dividendo 11 per 3.
+ somma - differenza * moltiplicazione / divisione % modulo (o resto)
valore += incremento; è equivalente a valore = valore + incremento;e analogamente per le altre operazioni.
a -= 5; è equivalente ad a = a - 5;
a /= b; è equivalente ad a = a / b;
prezzo *= numero + 1; è equivalente a prezzo = prezzo * (numero + 1);
a++;fanno la stessa cosa: aumentano di 1 il valore di a.
a += 1;
a = a+1;
Questi operatori si possono usare sia come prefissi che come postfissi . Ossia possono essere scritti prima della variabile ( ++a ) o dopo di essa ( a++ ). Benché in espressioni semplici come a++ o ++a gli operatori prefissi e postfissi abbiano lo stesso significato, in altri casi in cui viene utilizzato il risultato dell'operazione nella valutazione di un'altra espressione essi assumono un significato diverso: Se l'operatore di incremento viene usato come prefisso ( ++a ) il valore della variabile viene incrementato prima della valutazione dell'espressione e quindi l'espressione viene valutata usando il valore incrementato; se l'operatore di incremento viene usato come postfisso ( a++ ) il valore della variabile viene incrementato dopo la valutazione dell'espressione e quindi l'espressione viene valutata usando il valore non incrementato. Ecco un esempio della differenza tra i due modi di usare l'operatore:
Nel primo esempio, la variabile B viene incrementata prima che il suo valore venga copiato in A mentre nel secondo esempio viene prima copiato in A il valore della variabile B e poi viene incrementato il valore della variabile B.
Esempio 1 Esempio 2 B = 3;
A = ++B;
// A è 4, B è 4B = 3;
A = B++;
// A è 3, B è 4
Ecco la lista degli operatori relazionali del C++:
Ed ecco alcuni esempi:
== Uguale != Diverso > Maggiore < Minore >= Maggiore o uguale <= Minore o uguale
naturalmente, invece di usare soltanto costanti numeriche possiamo usare qualunque espressioni valida, comprese le variabili. Supponiamo che a=2, b=3e c=6,
(7 == 5) risultato false . (5 > 4) risultato true . (3 != 2) risultato true . (6 >= 6) risultato true . (5 < 5) risultato false .
Attenzione. L'operatore = (un solo uguale) è differente dal simbolo == (doppio uguale), il primo è l'operatore di assegnamento (assegna il valore dell'espressione alla sua destra alla variabile alla sua sinistra e ritorna tale valore) mentre il secondo è l'operatore relazionale di uguaglianza che confronta i valori delle due espressioni che stanno ai suoi lati e ritorna il valore booleano true o false a seconda che esse abbiano lo stesso valore o valori diversi. Quindi nell'ultima espressione ((b=2) == a), viene dapprima assegnato il valore 2 a b e quindi tale valore viene confrontato con il valore di a, che è pure 2, e quindi il risultato che si ottiene è il valore true.
(a == 5) risultato false. (a*b >= c) risultato true in quanto (2*3 >= 6). (b+4 > a*c) risultato false in quanto (3+4 > 2*6). ((b=2) == a) risultato true.
In molti compilatori precedenti la pubblicazione dello standard ANSI-C++, come pure in C, gli operatori relazionali non ritornano un valore bool (true o false ) ma ritornano un valore int con 0 che rappresenta "false" e un valore diverso da 0 (in genere 1 ) che rappresenta "true" . |
Gli operatori && e || sono gli operatori logici di congiunzione (AND) e disgiunzione (OR). Essi hanno due operandi (di tipo bool), uno alla sinistra ed uno alla destra, e il risultato è quello riportato nella seguente tabella:
!(5 == 5) ritorna false in quanto l'espressione alla sua destra (5 == 5) è true . !(6 <= 4) ritorna true in quanto (6 <= 4) è false . !true ritorna false. !false ritorna true.
Ad esempio:
Primo
operando
aSecondo
operando
bRisultato
di
a && bRisultato
di
a || btrue true true true true false false true false true false true false false false false
( (5 == 5) && (3 > 6) ) ritorna false ( true && false ).
( (5 == 5) || (3 > 6) ) ritorna true ( true || false ) .
condizione ? risultato1 : risultato2se condizione è true l'espressione ritorna risultato1, altrimenti ritorna risultato2.
7==5 ? 4 : 3 ritorna 3 perché 7 non è uguale a 5 . 7==5+2 ? 4 : 3 ritorna 4 perché 7 è uguale a 5+2 . 5>3 ? a : b ritorna a, perché 5 è maggiore di 3 . a>b ? a : b ritorna il maggiore dei due, a o b .
operatore assembler Descrizione & AND AND bit a bit | OR OR bit a bit ^ XOR OR esclusivo bit a bit ~ NOT NOT bit a bit (complemento a uno) << SHL Spostamento dei bit (shift) a sinistra >> SHR Spostamento dei bit (shift) a destra
int i;Il codice precedente converte il numero float 3.14 nel valore intero 3. L'operatore di conversione è rappresentato da (int). Un modo più consono allo stile C++ è quello di usare la funzione costruttore: far precedere l'espressione da convertire, racchiusa tra parentesi, dal nome del nuovo tipo.
float f = 3.14;
i = (int) f;
i = int ( f );Entrambe le forme sono accettate dallo standard ANSI-C++ che inoltre ha aggiunto altri tipi di conversione adatti alla programmazione ad oggetti. (vedi Sezione 5.4, Conversioni di tipo avanzate).
a = sizeof (char);ritorna 1 in a perché un valore di tipo char occupa un byte.
a = 5 + 7 % 2può sorgere il dubbio tra le seguenti due interpretazioni:
a = 5 + (7 % 2) con risultato 6, oL'interpretazione corretta è la prima, quella con risultato 6. Vi è un ordine di priorità prestabilito tra tutti gli operatori (sia aritmetici che non aritmetici). L'ordine di priorità è il seguente:
a = (5 + 7) % 2 con risultato 0
L'associatività specifica in quale ordine vengono valutati gli operatori con la stessa priorità: partendo da quello più a destra o da quello più a sinistra.
Priorità Operatore Descrizione Associatività 1 :: scopo Sinistra 2 () [ ] -> . sizeof Sinistra 3 ++ -- incremento/decremento Destra ~ Complemento a uno (bit a bit) ! NOT & * Referenziazione e Dereferenziazione (puntatori) (tipo) Conversione di tipo + - Operatori di segno unario 4 * / % Operatori aritmetici moltiplicativi Sinistra 5 + - Operatori aritmetici additivi Sinistra 6 << >> Spostamento dei bit Sinistra 7 < <= > >= Operatori relazionali Sinistra 8 == != Operatori relazionali di uguaglianza Sinistra 9 & ^ | Operatori bit a bit Sinistra 10 && || Operatori logici Sinistra 11 ?: Operatore condizionale Destra 12 = += -= *= /= %=
>>= <<= &= ^= |=Assegnamento Destra 13 , Operatore virgola, separatore Sinistra
La precedenza degli operatori in una espressione si può modificare o rendere evidente usando le parentesi ( e ) come nell'esempio seguente:
a = 5 + 7 % 2;si può scrivere come:
a = 5 + (7 % 2);oppurea seconde di come si vuole venga eseguita l'espressione.
a = (5 + 7) % 2;
Pertanto, quando si vuole scrivere una espressione complicata e non
si è certi della precedenza degli operatori è bene mettere
le parentesi; questo renderà oltretutto più leggibile l'espressione.
Precedente:
1-2. Variabili, tipi di dato, costanti. |
indice |
Successivo:
1-4. Comunicazione da console. |