Quella che segue è una tabella che elenca la precedenza e l’associatività di tutti gli operatori nei linguaggi C e C++ (quando gli operatori esistono anche in Java, Perl, PHP e molti altri linguaggi recenti, la precedenza è la stessa di quella data). Gli operatori sono elencati dall’alto verso il basso, in precedenza decrescente. La precedenza decrescente si riferisce alla priorità del raggruppamento degli operatori e degli operandi. Considerando un’espressione, un operatore che è elencato su qualche riga sarà raggruppato prima di qualsiasi operatore che è elencato su una riga più in basso. Gli operatori che si trovano nella stessa cella (ci possono essere più righe di operatori elencati in una cella) sono raggruppati con la stessa precedenza, nella direzione data. La precedenza di un operatore non è influenzata dall’overloading.
La sintassi delle espressioni in C e C++ è specificata da una grammatica a struttura di frase. La tabella fornita qui è stata dedotta dalla grammatica. Per lo standard ISO C 1999, la sezione 6.5.6 nota 71 afferma che la grammatica C fornita dalla specifica definisce la precedenza degli operatori C, e afferma anche che la precedenza degli operatori risultante dalla grammatica segue da vicino l’ordine delle sezioni della specifica:
“La sintassi specifica la precedenza degli operatori nella valutazione di un’espressione, che è la stessa dell’ordine delle principali sottoclausole di questa sottoclausola, precedenza più alta per prima.”
Una tabella di precedenza, anche se per lo più adeguata, non può risolvere alcuni dettagli. In particolare, si noti che l’operatore ternario permette qualsiasi espressione arbitraria come operando centrale, nonostante sia elencato come avente una precedenza più alta degli operatori di assegnazione e di virgola. Così a ? b, c : d
viene interpretato come a ? (b, c) : d
, e non come l’insensato (a ? b), (c : d)
. Quindi, l’espressione nel mezzo dell’operatore condizionale (tra ?
e :
) viene analizzata come se fosse una parentesi. Inoltre, si noti che il risultato immediato, non parentetizzato, di un’espressione C cast non può essere l’operando di sizeof
. Pertanto, sizeof (int) * x
viene interpretato come (sizeof(int)) * x
e non sizeof ((int) * x)
.
NoteEdit
La tabella di precedenza determina l’ordine di legame nelle espressioni concatenate, quando non è espressamente specificato dalle parentesi.
Precedenza e legami
Molti degli operatori che contengono sequenze di più caratteri hanno dei “nomi” costruiti dal nome dell’operatore di ogni carattere. Per esempio, +=
e -=
sono spesso chiamati più uguale(i) e meno uguale(i), invece dei più verbosi “assegnazione per addizione” e “assegnazione per sottrazione”.Il binding degli operatori in C e C++ è specificato (negli standard corrispondenti) da una grammatica di linguaggio fattorizzata, piuttosto che da una tabella di precedenza. Questo crea alcuni sottili conflitti. Per esempio, in C, la sintassi per un’espressione condizionale è:
logical-OR-expression ? expression : conditional-expression
mentre in C++ è:
logical-OR-expression ? expression : assignment-expression
Quindi, l’espressione:
e = a < d ? a++ : a = d
viene analizzata diversamente nei due linguaggi. In C, questa espressione è un errore di sintassi, perché la sintassi per un’espressione di assegnazione in C è:
unary-expression '=' assignment-expression
In C++, viene analizzata come:
e = (a < d ? a++ : (a = d))
che è un’espressione valida.
int a = 1, b = 2, weirdVariable = (++a, b), d = 4;
Critica della precedenza degli operatori bitwise e di uguaglianzaEdit
La precedenza degli operatori logici bitwise è stata criticata. Concettualmente, & e | sono operatori aritmetici come * e +.
Inoltre, in C++ (e versioni successive del C) le operazioni di uguaglianza, ad eccezione dell’operatore di confronto a tre vie, producono valori di tipo bool che sono concettualmente un singolo bit (1 o 0) e come tali non appartengono propriamente alle operazioni “bitwise”.
Sinonimi di operatori C++Modifica
C++ definisce alcune parole chiave che fungono da alias per un certo numero di operatori:
Parola chiave | Operatore |
---|---|
e |
&& |
eq |
&= |
bitand |
& |
bitor |
| |
compl |
~ |
non |
! |
not_eq |
!= |
or |
|| |
or_eq |
|= |
xor |
^ |
xor_eq |
^= |
Questi possono essere usati esattamente come i simboli di punteggiatura che sostituiscono, poiché non sono lo stesso operatore con un nome diverso, ma piuttosto semplici sostituzioni di token per il nome (stringa di caratteri) del rispettivo operatore. Ciò significa che le espressioni (a > 0 e non flag)
e (a >&& !flag)
hanno un significato identico. Significa anche che, per esempio, la parola chiave bitand
può essere usata per sostituire non solo l’operatore bitwise-and ma anche l’operatore address-of, e può anche essere usata per specificare tipi di riferimento (per esempio, int bitand ref = n
). La specifica ISO C permette queste parole chiave come macro di preprocessore nel file di intestazione iso646.h
. Per compatibilità con il C, il C++ fornisce l’intestazione ciso646
, la cui inclusione non ha effetto.