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à.

  1. ::
  2. Gli operatori postfix: [] () T(...) . -> ++ -- dynamic_cast static_cast reinterpret_cast const_cast typeid
  3. Gli operatori del prefisso unario: ++ -- * & + - ! ~ sizeof new delete delete[] ; la notazione cast in stile C, (T)... ; (C ++ 11 e successivi) sizeof... alignof noexcept
  4. .* e ->*
  5. * , / , e % , operatori aritmetici binari
  6. + e - , operatori aritmetici binari
  7. << e >>
  8. < , > , <= , >=
  9. == e !=
  10. & , l'operatore AND bit a bit
  11. ^
  12. |
  13. &&
  14. ||
  15. ?: (operatore condizionale ternario)
  16. = , *= , /= , %= , += , -= , >>= , <<= , &= , ^= , |=
  17. throw
  18. , (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 come a ? b , c : d per essere sintatticamente valido.
  • Un operando si lega più strettamente ad un ? alla sua destra che a un operatore di assegnazione o di throw alla sua sinistra, quindi a = b ? c : d è equivalente a a = (b ? c : d) e throw a ? b : c è equivalente al throw (a ? b : c) .
  • Un operando si lega più strettamente a un operatore incaricato alla sua destra che a : a sinistra, quindi a ? b : c = d è equivalente a a ? 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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow