C++
precedenza dell'operatore
Ricerca…
Osservazioni
Gli operatori sono elencati dall'alto in basso, in ordine decrescente. Gli operatori con lo stesso numero hanno la stessa priorità e la stessa associatività.
-
:: - Gli operatori postfix:
[]()T(...).->++--dynamic_caststatic_castreinterpret_castconst_casttypeid - Gli operatori del prefisso unario:
++--*&+-!~sizeofnewdeletedelete[]; la notazione cast in stile C,(T)...; (C ++ 11 e successivi)sizeof...alignofnoexcept -
.*e->* -
*,/, e%, operatori aritmetici binari -
+e-, operatori aritmetici binari -
<<e>> -
<,>,<=,>= -
==e!= -
&, l'operatore AND bit a bit -
^ -
| -
&& -
|| -
?:(operatore condizionale ternario) -
=,*=,/=,%=,+=,-=,>>=,<<=,&=,^=,|= -
throw -
,(operatore virgola)
L'assegnazione, l'assegnazione composta e gli operatori condizionali ternari sono giusti-associativi. Tutti gli altri operatori binari sono associati a sinistra.
Le regole per l'operatore condizionale ternario sono un po 'più complicate di quanto possano esprimere le regole di precedenza semplici.
- Un operando si lega meno strettamente ad un
?alla sua sinistra o a:a destra rispetto a qualsiasi altro operatore. In effetti, il secondo operando dell'operatore condizionale viene analizzato come se fosse tra parentesi. Questo consente un'espressione comea ? b , c : dper essere sintatticamente valido. - Un operando si lega più strettamente ad un
?alla sua destra che a un operatore di assegnazione o dithrowalla sua sinistra, quindia = b ? c : dè equivalente aa = (b ? c : d)ethrow a ? b : cè equivalente althrow (a ? b : c). - Un operando si lega più strettamente a un operatore incaricato alla sua destra che a
:a sinistra, quindia ? b : c = dè equivalente aa ? b : (c = d).
Operatori aritmetici
Gli operatori aritmetici in C ++ hanno la stessa precedenza in matematica:
Moltiplicazione e divisione hanno lasciato l'associatività (il che significa che saranno valutati da sinistra a destra) e hanno una precedenza più alta di addizioni e sottrazioni, che hanno anche lasciato associatività.
Possiamo anche forzare la precedenza dell'espressione usando parentesi ( ) . Proprio come faresti nella matematica normale.
// volume of a spherical shell = 4 pi R^3 - 4 pi r^3
double vol = 4.0*pi*R*R*R/3.0 - 4.0*pi*r*r*r/3.0;
//Addition:
int a = 2+4/2; // equal to: 2+(4/2) result: 4
int b = (3+3)/2; // equal to: (3+3)/2 result: 3
//With Multiplication
int c = 3+4/2*6; // equal to: 3+((4/2)*6) result: 15
int d = 3*(3+6)/9; // equal to: (3*(3+6))/9 result: 3
//Division and Modulo
int g = 3-3%1; // equal to: 3 % 1 = 0 3 - 0 = 3
int h = 3-(3%1); // equal to: 3 % 1 = 0 3 - 0 = 3
int i = 3-3/1%3; // equal to: 3 / 1 = 3 3 % 3 = 0 3 - 0 = 3
int l = 3-(3/1)%3; // equal to: 3 / 1 = 3 3 % 3 = 0 3 - 0 = 3
int m = 3-(3/(1%3)); // equal to: 1 % 3 = 1 3 / 1 = 3 3 - 3 = 0
Operatori logici AND e OR
Questi operatori hanno la solita precedenza in C ++: AND before OR.
// You can drive with a foreign license for up to 60 days
bool can_drive = has_domestic_license || has_foreign_license && num_days <= 60;
Questo codice è equivalente al seguente:
// You can drive with a foreign license for up to 60 days
bool can_drive = has_domestic_license || (has_foreign_license && num_days <= 60);
L'aggiunta della parentesi non modifica il comportamento, tuttavia facilita la lettura. Aggiungendo queste parentesi, non c'è confusione sull'intento dello scrittore.
Logico && e || operatori: cortocircuito
&& ha la precedenza su ||, questo significa che vengono poste parentesi per valutare cosa sarebbe valutato insieme.
c ++ utilizza la valutazione di cortocircuito in && e || non fare esecuzioni inutili.
Se il lato sinistro di || ritorna vero il lato destro non ha più bisogno di essere valutato.
#include <iostream>
#include <string>
using namespace std;
bool True(string id){
cout << "True" << id << endl;
return true;
}
bool False(string id){
cout << "False" << id << endl;
return false;
}
int main(){
bool result;
//let's evaluate 3 booleans with || and && to illustrate operator precedence
//precedence does not mean that && will be evaluated first but rather where
//parentheses would be added
//example 1
result =
False("A") || False("B") && False("C");
// eq. False("A") || (False("B") && False("C"))
//FalseA
//FalseB
//"Short-circuit evaluation skip of C"
//A is false so we have to evaluate the right of ||,
//B being false we do not have to evaluate C to know that the result is false
result =
True("A") || False("B") && False("C");
// eq. True("A") || (False("B") && False("C"))
cout << result << " :=====================" << endl;
//TrueA
//"Short-circuit evaluation skip of B"
//"Short-circuit evaluation skip of C"
//A is true so we do not have to evaluate
// the right of || to know that the result is true
//If || had precedence over && the equivalent evaluation would be:
// (True("A") || False("B")) && False("C")
//What would print
//TrueA
//"Short-circuit evaluation skip of B"
//FalseC
//Because the parentheses are placed differently
//the parts that get evaluated are differently
//which makes that the end result in this case would be False because C is false
}
Operatori unari
Gli operatori unari agiscono sull'oggetto su cui sono chiamati e hanno un'alta precedenza. (Vedi Note)
Quando viene usato postfix, l'azione si verifica solo dopo aver valutato l'intera operazione, portando ad alcune aritmetiche interessanti:
int a = 1;
++a; // result: 2
a--; // result: 1
int minusa=-a; // result: -1
bool b = true;
!b; // result: true
a=4;
int c = a++/2; // equal to: (a==4) 4 / 2 result: 2 ('a' incremented postfix)
cout << a << endl; // prints 5!
int d = ++a/2; // equal to: (a+1) == 6 / 2 result: 3
int arr[4] = {1,2,3,4};
int *ptr1 = &arr[0]; // points to arr[0] which is 1
int *ptr2 = ptr1++; // ptr2 points to arr[0] which is still 1; ptr1 incremented
std::cout << *ptr1++ << std::endl; // prints 2
int e = arr[0]++; // receives the value of arr[0] before it is incremented
std::cout << e << std::endl; // prints 1
std::cout << *ptr2 << std::endl; // prints arr[0] which is now 2