Un operatore è un istruzione che agisce sui dei dati, detti operandi, allo scopo di ottenere un risultato.
Quando in un’istruzione si incontrano diversi operatori, l’ordine di esecuzione é tipicamente da sinistra verso destra, sebbene vi siano anche operatori che agiscono nel modo opposto. L’apposizione di parentesi tonde ( ) attribuisce all’operatore ivi contenuto priorità d’esecuzione rispetto ad altri operatori contenuti nella stessa espressione. In caso di doppia parentesi ( 1 + 1 + ( 1 – 1)) la priorità viene assegnata alle parentesi più interne. Ciò premesso, vi sono casi in cui gli operatori non obbediscono a criteri logici di precedenza, ma tale precedenza é stabilita in fase di implementazione sulla base di criteri di efficienza, anche sulla base dell’hardware utilizzato.
In generale valgono le stesse precedenze valide in matematica, in base alle quali moltiplicazioni e divisioni hanno la precedenza su addizione e sottrazione.
Operatore di assegnamento ( o assegnazione)
Evitiamo esercizi dialettici squisitamente e meramente definitori: l’operatore di assegnamento = viene tipicamente utilizzato per assegnare un valore ad una variabile.
Operatori aritmetici
Gli operatori aritmetici sono quelli tipici dell’aritmetica ( + – * / ) ed operano allo stesso identico modo, ma si aggiunge l’operatore modulo ( % ) che serve restituisce il resto di una divisione, ampiamente utilizzato per valutare se un numero é pari o dispari.
Operatori unari
Vengono tipicamente utilizzati per restituire lo stesso valore di un operando senza alternarne il segno, o alterandolo.
Operatori unari di incremento o decremento
Gli operatori unari di incremento (++) o decremento (–) sono utilizzati per sottrarre 1 all’operando. Trovano largo impiego nei contatori. Questi operatori possono essere prefissi (preincremento) o postfissi (postincremento). Nel primo caso l’operazione di incremento avviene prima della valutazione della variabile, nel secondo avviene dopo. E’ bene valutare il loro utilizzo ed il loro inserimento in modo ragionato perché quando situati nella stessa espressione, possono dare luogo ad anomalie date dall’incerta priorità di valutazione della variabile stessa.
Operatori relazionali
Sono rappresentato dai segni maggiore o minore cui si aggiunge il segno uguale, così come avviene in matematica. Il risultato dell’operazione può essere true o false. Così se a > b il risultato sarà true, in caso contrario sarà false. Opportunamente abbinati al simbolo ( = ), producono un’operazione di confronto che si estende all’uguaglianza tra gli operandi.
Operatori di uguaglianza
A differenza degli operatori di assegnamento, gli operatori di uguaglianza si rappresentano con due simboli (==). E’ un errore comune che ne venga indicato uno solo. Lo scopo di questo operatore è effettuare il confronto tra due operandi e restituire true in caso di uguaglianza.
Operatore di disuguaglianza
Molto utilizzato, al pari del precedente ha un funzionamento diametralmente opposto, restituisce true in caso di disuguaglianza.
Operatori Logici
Operano con le logiche tipiche dell’algebra booleana. Sono definite anche “porte logiche” e sono: OR ( | |, somma), AND (&&, moltiplicazione), NOT ( ! , negazione, inversione). Il risultato di queste operazioni é tipicamente definito attraverso una tabella della verità:
Porta AND &&
1 ° operando | 2° operando | && AND |
False | False | False |
False | True | False |
True | False | False |
True | True | True |
NB: l’espressione é true solo se entrambi gli operandi sono true.
Porta OR | |
1 ° operando | 2° operando | | | OR |
False | False | False |
False | True | True |
True | False | True |
True | True | True |
NB: l’espressione é true se anche solo uno degli operandi è true.
Porta NOT !
operando | ! NOT |
False | True |
True | False |
NB: restituisce l’inverso di ciò che riceve.
Operatori Condizionali
Gli operatori condizionali sono composti da tre operando e sono rappresentati dalla struttura:
Operando_1 ? Operando_2 : Operando_3;
Se il primo operando é true, valuta il secondo, se é false, valuta il terzo.
Operatori bit per bit
Gli operatori bit per bit svolgono le medesime operazioni degli operatori sopra elencati, ma operano a basso livello, sui singoli bit memorizzati in memoria. Il loro utilizzo può rivelarsi molto utile quando si deve andare ad intervenire su un valore in memoria in modo molto selettivo.
~ | Operatore di complemento ad uno |
& | Operatore and bit per bit |
| | Operatore OR |
^ | Operatore XOR |
<< | Scorrimento a sinistra bit per bit |
>> | Scorrimento a destra bit per bit |
Tabella della verità
A | B | ~A | A&B | A|B | A^B |
0 | 0 | 1 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 1 | 1 |
0 | 1 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 1 | 1 | 0 |
Operatore di complemento a uno
Produce la negazione (l’inverso) del suo operando a livello di bit per bit.
Operatore AND bit per bit
L’operatore AND bit per bit si identifica con il simbolo & e svolge la medesima operazione dell’operatore AND, ma bit per bit, il che produce un risultato differente da quest’ultimo. I bit relativi all’operatore in memoria vengono valutati uno per uno e il risultato é prodotto booleano di questa comparazione.
Operatore OR bit per bit
L’operatore OR per bit inclusivo, si identifica con il simbolo | e svolge un funzione OR bit per bit. Il risultato è la somma booleana degli operatori, cioè restituisce true se almeno uno dei suoi operando è true.
Operatore XOR bit per bit
Simile al precedente, ma restituisce true solo nel caso che uno solo dei suoi operandi sia true.
Operatore di scorrimento a sinistra per per bit
L’operatore di scorrimento a sinistra bit per bit, scorre a sinistra i bit dell’operando di sinistra di tante posizioni quante quelle indicate dall’operando di destra. I valori introdotti da destra saranno 0. Se il primo operando é di segno negativo il risultato non sarà definito.
Operatore di scorrimento a destra per per bit
L’operatore di scorrimento a destra bit per bit, scorre a destra i bit dell’operando di sinistra di tante posizioni quante quelle indicate dall’operando di destra. I valori introdotti da destra saranno 0. Se il primo operando é di segno negativo il risultato non sarà definito. Il comportamento potrà dipendere dall’implementazione.
L’operatore virgola
In alcuni casi si tratta di un comune separatore, in altri invece agisce come un combinatore di espressioni, garantendo che i sequence point abbiano avuto effetto (che le operazioni siano state effettivamente eseguite). Sono utilizzati spesso nei cicli for per aggiornare 2 o più variabili.
Operatori di assegnamento composti
Aggiungendo il simbolo ( = ) ad uno dei precedenti operatori (es: &=) si svolge contestualmente all’operazione prevista anche l’assegnamento del valore. Occorre valutare che la priorità con cui viene eseguita è subordinata ad altre operazioni, come ad esempio quelle di tipo aritmetico, per cui può tornare utile servirsi della seguente tabella:
Tabella di precedenza
Priorità | Operatore | Nome | Associazione |
1 | [] | Array | Sx → Dx |
1 | () | Funzione o raggruppamento | Sx → Dx |
1 | . | Accesso membro struttura | Sx → Dx |
1 | -> | Accesso membro struttura puntatore | Sx → Dx |
1 | ++ | Incremento Postfisso | Sx → Dx |
1 | — | Decremento Postfisso | Sx → Dx |
1 | (type)(list) | Letterale composto | Sx → Dx |
2 | ++ | Incremento prefisso | Dx → Sx |
2 | — | Decremento prefisso | Dx → Sx |
2 | + | Più unario | Dx → Sx |
2 | – | Meno unario | Dx → Sx |
2 | & | Indirizzo | Dx → Sx |
2 | * | Deriferimento | Dx → Sx |
2 | ~ | Complemento a 1 | Dx → Sx |
2 | ! | NOT | Dx → Sx |
2 | (type) | Cast | Dx → Sx |
2 | sizeof | Dimensione di un operando | Dx → Sx |
2 | _Alignof | Allineamento di un operando | Dx → Sx |
3 | * | Moltiplicazione | Sx → Dx |
3 | / | Divisione | Sx → Dx |
3 | % | Modulo | Sx → Dx |
4 | + | Addizione | Sx → Dx |
4 | – | Sottrazione | Sx → Dx |
5 | << | Scorrimento a sinistra bit per bit | Sx → Dx |
5 | >> | Scorrimento a destra bit per bit | Sx → Dx |
6 | < | Minore di | Sx → Dx |
6 | <= | Minore o uguale a | Sx → Dx |
6 | > | Maggiore di | Sx → Dx |
6 | >= | Maggiore o uguale a | Sx → Dx |
7 | == | Uguale a | Sx → Dx |
7 | != | Diverso da | Sx → Dx |
8 | & | And bit per bit | Sx → Dx |
9 | ^ | OR bit per bit esclusivo | Sx → Dx |
10 | | | OR bit per bit inclusivo | Sx → Dx |
11 | && | AND | Sx → Dx |
12 | || | OR | Sx → Dx |
13 | ?: | Operatore condizionale | Dx → Sx |
14 | = | Assegnamento semplice | Dx → Sx |
14 | += -= *= /= | Operatori di assegnamento composti | Dx → Sx |
14 | %= |= ^= | Operatori di assegnamento composti | Dx → Sx |
14 | <<= >>= | Scorrimento e assegnamento | Dx → Sx |
15 | , | Virgola | Sx → Dx |