C++
operatörens företräde
Sök…
Anmärkningar
Operatörerna listas uppifrån och ned, i fallande prioritet. Operatörer med samma antal har samma prioritet och samma associativitet.
-
::
- Postfixoperatörerna:
[]
()
T(...)
.
->
++
--
dynamic_cast
static_cast
reinterpret_cast
const_cast
typeid
- De unära prefixoperatörerna:
++
--
*
&
+
-
!
~
sizeof
new
delete
delete[]
; C-stil cast notation,(T)...
; (C ++ 11 ochsizeof...
)sizeof...
alignof
noexcept
-
.*
och->*
-
*
,/
och%
, binära aritmetiska operatörer -
+
och-
, binära aritmetiska operatörer -
<<
och>>
-
<
,>
,<=
,>=
-
==
och!=
-
&
, den bitvisa OCH-operatören -
^
-
|
-
&&
-
||
-
?:
(ternary villkorad operatör) -
=
,*=
,/=
,%=
,+=
,-=
,>>=
,<<=
,&=
,^=
,|=
-
throw
-
,
(kommaoperatören)
Uppdraget, sammansatt tilldelning och ternära villkorade operatörer är rätt associerande. Alla andra binära operatörer är vänsterassocierande.
Reglerna för den ternära villkorade operatören är lite mer komplicerade än enkla företrädesregler kan uttrycka.
- En operand binder mindre snävt till en
?
till vänster eller a:
till höger än till någon annan operatör. Effektivt parsas den andra operanden för den villkorade operatören som om den är parenteserad. Detta tillåter ett uttryck soma ? b , c : d
att vara syntaktiskt giltig. - En operand binder sig tätare till en
?
till höger än till en uppdragsoperatör ellerthrow
till vänster, såa = b ? c : d
motsvarara = (b ? c : d)
ochthrow a ? b : c
motsvararthrow (a ? b : c)
. - En operand binder sig tätare till en uppdragsoperatör till höger än till
:
till vänster, såa ? b : c = d
motsvarara ? b : (c = d)
.
Aritmetiska operatörer
Aritmetiska operatörer i C ++ har samma företräde som de gör i matematik:
Multiplikation och delning har lämnat associativitet (vilket betyder att de kommer att utvärderas från vänster till höger) och de har högre företräde än tillägg och subtraktion, som också har vänsterassociativitet.
Vi kan också tvinga uttryckets företräde med parenteser (
)
. På samma sätt som du skulle göra det i normal matematik.
// 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
Logiska OCH och ELLER operatörer
Dessa operatörer har den vanliga föregången i C ++: OCH före ELLER.
// You can drive with a foreign license for up to 60 days
bool can_drive = has_domestic_license || has_foreign_license && num_days <= 60;
Den här koden motsvarar följande:
// You can drive with a foreign license for up to 60 days
bool can_drive = has_domestic_license || (has_foreign_license && num_days <= 60);
Att lägga till parentes förändrar inte beteendet, men det gör det lättare att läsa. Genom att lägga till dessa parenteser finns det ingen förvirring om författarens avsikt.
Logisk && och || operatörer: kortslutning
&& har företräde framför ||, detta innebär att parenteser placeras för att utvärdera vad som skulle utvärderas tillsammans.
c ++ använder kortslutningsutvärdering i && och || att inte göra onödiga avrättningar.
Om vänster sida av || returnerar sant den högra sidan behöver inte utvärderas längre.
#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
}
Unary Operators
Olika operatörer agerar på det objekt som de kallas på och har hög prioritet. (Se anmärkningar)
Vid användning efter postfix sker åtgärden först efter att hela operationen har utvärderats, vilket leder till intressant aritmetik:
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