C++中的运算符优先级详解
C++运算符优先级,是描述在计算机运算计算表达式时执行运算的先后顺序。 先执行具有较高优先级的运算,然后执行较低优先级的运算。 例如,我们常说的先执行相乘和除,再执行加减运算。
C++运算符优先级表
优先级 |
运算符 |
说明 |
结合性 |
---|---|---|---|
1 |
:: |
范围解析 |
自左向右 |
2 |
++ -- |
后缀自增/后缀自减 |
|
() |
括号 |
||
[] |
数组下标 |
||
. |
成员选择(对象) |
||
−> |
成员选择(指针) |
||
3 |
++ -- |
前缀自增/前缀自减 |
自右向左 |
+ − |
加/减 |
||
! ~ |
逻辑非/按位取反 |
||
(type) |
强制类型转换 |
||
* |
取指针指向的值 |
||
& |
某某的地址 |
||
sizeof |
某某的大小 |
||
new,new[] |
动态内存分配/动态数组内存分配 |
||
delete,delete[] |
动态内存释放/动态数组内存释放 |
||
4 |
.* ->* |
成员对象选择/成员指针选择 |
自左向右 |
5 |
* / % |
乘法/除法/取余 |
|
6 |
+ − |
加号/减号 |
|
7 |
<< >> |
位左移/位右移 |
|
8 |
< <= |
小于/小于等于 |
|
> >= |
大于/大于等于 |
||
9 |
== != |
等于/不等于 |
|
10 |
& |
按位与 |
|
11 |
^ |
按位异或 |
|
12 |
| |
按位或 |
|
13 |
&& |
与运算 |
|
14 |
|| |
或运算 |
|
15 |
?: |
三目运算符 |
自右向左 |
16 |
= |
赋值 |
|
+= −= |
相加后赋值/相减后赋值 |
||
*= /= %= |
相乘后赋值/相除后赋值/取余后赋值 |
||
<<= >>= |
位左移赋值/位右移赋值 |
||
&= ^= |= |
位与运算后赋值/位异或运算后赋值/位或运算后赋值 |
||
17 |
throw |
抛出异常 |
|
18 |
, |
逗号 |
自左向右 |
C#运算符优先级举例说明
优先级 |
操作符 |
描述 |
例子 |
结合性 |
---|---|---|---|---|
1 |
()[]->.::++-- |
调节优先级的括号操作符数组下标访问操作符通过指向对象的指针访问成员的操作符通过对象本身访问成员的操作符作用域操作符后置自增操作符后置自减操作符 |
(a+b)/4;array[4]=2;ptr->age=34;obj.age=34;Class::age=2;for(i=0;i<10;i++)...for(i=10;i>0;i--)... |
从左到右 |
2 |
!~++---+*&(type)sizeof |
逻辑取反操作符按位取反(按位取补) 前置自增操作符前置自减操作符一元取负操作符一元取正操作符解引用操作符取地址操作符类型转换操作符返回对象占用的字节数操作符 |
if(!done)...flags=~flags;for(i=0;i<10;++i)...for(i=10;i>0;--i)...int i=-1;int i=+1;data=*ptr;address=&obj;int i=(int)floatNum;int size=sizeof(floatNum); |
从右到左 |
3 |
->*.* |
在指针上通过指向成员的指针访问成员的操作符在对象上通过指向成员的指针访问成员的操作符 |
ptr->*var=24;obj.*var=24; |
从左到右 |
4 |
*/% |
乘法操作符除法操作符取余数操作符 |
int i=2*4;float f=10/3;int rem=4%3; |
从左到右 |
5 |
+- |
加法操作符减法操作符 |
int i=2+3;int i=5-1; |
从左到右 |
6 |
<<>> |
按位左移操作符按位右移操作符 |
int flags=33<<1;int flags=33>>1; |
从左到右 |
7 |
<<=>>= |
小于比较操作符小于或等于比较操作符大于比较操作符大于或等于比较操作符 |
if(i<42)...if(i<=42)...if(i>42)...if(i>=42)... |
从左到右 |
8 |
==!= |
等于比较操作符不等于比较操作符 |
if(i==42)...if(i!=42)... |
从左到右 |
9 |
& |
按位与操作符 |
flags=flags&42; |
从左到右 |
10 |
^ |
按位异或操作符 |
flags=flags^42; |
从左到右 |
11 |
| |
按位或操作符 |
flags=flags|42; |
从左到右 |
12 |
&& |
逻辑与操作符 |
if(conditionA&&conditionB)... |
从左到右 |
13 |
|| |
逻辑或操作符 |
if(conditionA||conditionB)... |
从左到右 |
14 |
?: |
三元条件操作符 |
int i=(a>b)?a:b; |
从右到左 |
15 |
=+=-=*=/=%=&=^=|=<<=>>= |
赋值操作符复合赋值操作符(加法)复合赋值操作符(减法)复合赋值操作符(乘法)复合赋值操作符(除法)复合赋值操作符(取余)复合赋值操作符(按位与)复合赋值操作符(按位异或)复合赋值操作符(按位或)复合赋值操作符(按位左移)复合赋值操作符(按位右移) |
int a=b;a+=3;b-=4;a*=5;a/=2;a%=3;flags&=new_flags;flags^=new_flags;flags|=new_flags;flags<<=2;flags>>=2; |
从右到左 |
16 |
, |
逗号操作符 |
for(i=0,j=0;i<10;i++,j++)... |
从左到右 |
C++中的运算符和运算符优先级总结(摘抄)
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C++ 内置了丰富的运算符,并提供了以下类型的运算符:
- 算术运算符。
- 关系运算符。
- 逻辑运算符。
- 位运算符。
- 赋值运算符。
- 杂项运算符。
一、算术运算符
下表显示了 C++ 支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:
运算符 |
描述 |
实例 |
---|---|---|
+ |
把两个操作数相加 |
A+B将得到30 |
- |
从第一个操作数中减去第二个操作数 |
A-B将得到-10 |
* |
把两个操作数相乘 |
A*B将得到200 |
/ |
分子除以分母 |
B/A将得到2 |
% |
取模运算符,整除后的余数 |
B%A将得到0 |
++ |
自增运算符,整数值增加1 |
A++将得到11 |
-- |
自减运算符,整数值减少1 |
A--将得到9 |
算术运算符实例:
请看下面的实例,了解 C++ 中所有可用的算术运算符,复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序即可。
#include <iostream>
using namespace std;
main()
{
int a = 21;
int b = 10;
int c ;
c = a + b;
cout << "Line 1 - c 的值是 " << c << endl ;
c = a - b;
cout << "Line 2 - c 的值是 " << c << endl ;
c = a * b;
cout << "Line 3 - c 的值是 " << c << endl ;
c = a / b;
cout << "Line 4 - c 的值是 " << c << endl ;
c = a % b;
cout << "Line 5 - c 的值是 " << c << endl ;
c = a++;
cout << "Line 6 - c 的值是 " << c << endl ;
c = a--;
cout << "Line 7 - c 的值是 " << c << endl ;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - c 的值是 31
Line 2 - c 的值是 11
Line 3 - c 的值是 210
Line 4 - c 的值是 2
Line 5 - c 的值是 1
Line 6 - c 的值是 21
Line 7 - c 的值是 22
}
二、关系运算符
下表显示了 C++ 支持的所有关系运算符。同样还是假设变量 A 的值为 10,变量 B 的值为 20,则:
运算符 |
描述 |
实例 |
---|---|---|
== |
检查两个操作数的值是否相等,如果相等则条件为真。 |
(A==B)不为真。 |
!= |
检查两个操作数的值是否相等,如果不相等则条件为真。 |
(A!=B)为真。 |
> |
检查左操作数的值是否大于右操作数的值,如果是则条件为真。 |
(A>B)不为真。 |
< |
检查左操作数的值是否小于右操作数的值,如果是则条件为真。 |
(A<B)为真。 |
>= |
检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 |
(A>=B)不为真。 |
<= |
检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 |
(A<=B)为真。 |
关系运算符实例:
请看下面的实例,了解 C++ 中所有可用的关系运算符,复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序即可。
#include <iostream>
using namespace std;
main()
{
int a = 21;
int b = 10;
int c ;
if( a == b )
{
cout << "Line 1 - a 等于 b" << endl ;
}
else
{
cout << "Line 1 - a 不等于 b" << endl ;
}
if ( a < b )
{
cout << "Line 2 - a 小于 b" << endl ;
}
else
{
cout << "Line 2 - a 不小于 b" << endl ;
}
if ( a > b )
{
cout << "Line 3 - a 大于 b" << endl ;
}
else
{
cout << "Line 3 - a 不大于 b" << endl ;
}
/* 改变 a 和 b 的值 */
a = 5;
b = 20;
if ( a <= b )
{
cout << "Line 4 - a 小于或等于 b" << endl ;
}
if ( b >= a )
{
cout << "Line 5 - b 大于或等于 b" << endl ;
}
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - a 不等于 b
Line 2 - a 不小于 b
Line 3 - a 大于 b
Line 4 - a 小于或等于 b
Line 5 - b 大于或等于 b
三、逻辑运算符
下表显示了 C++ 支持的所有关系逻辑运算符。假设变量 A 的值为 1,变量 B 的值为 0,则:
运算符 |
描述 |
实例 |
---|---|---|
&& |
称为逻辑与运算符。如果两个操作数都非零,则条件为真。 |
(A&&B)为假。 |
|| |
称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 |
(A||B)为真。 |
! |
称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 |
!(A&&B)为真。 |
逻辑运算符实例:
请看下面的实例,了解 C++ 中所有可用的逻辑运算符,复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序即可。
#include <iostream>
using namespace std;
main()
{
int a = 5;
int b = 20;
int c ;
if ( a && b )
{
cout << "Line 1 - 条件为真"<< endl ;
}
if ( a || b )
{
cout << "Line 2 - 条件为真"<< endl ;
}
/* 改变 a 和 b 的值 */
a = 0;
b = 10;
if ( a && b )
{
cout << "Line 3 - 条件为真"<< endl ;
}
else
{
cout << "Line 4 - 条件不为真"<< endl ;
}
if ( !(a && b) )
{
cout << "Line 5 - 条件为真"<< endl ;
}
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - 条件为真
Line 2 - 条件为真
Line 3 - 条件不为真
Line 4 - 条件为真
四、位运算符
位运算符作用于位,并逐位执行操作。&、 | 和 ^ 的真值表如下所示:
p |
q |
p&q |
p|q |
p^q |
---|---|---|---|---|
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
假设如果 A = 60,且 B = 13,现在以二进制格式表示,它们如下所示:
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
下表显示了 C++ 支持的位运算符。假设变量 A 的值为 60,变量 B 的值为 13,则:
运算符 |
描述 |
实例 |
---|---|---|
& |
如果同时存在于两个操作数中,二进制AND运算符复制一位到结果中。 |
(A&B)将得到12,即为0000 1100 |
| |
如果存在于任一操作数中,二进制OR运算符复制一位到结果中。 |
(A|B)将得到61,即为0011 1101 |
^ |
如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 |
(A^B)将得到49,即为0011 0001 |
~ |
二进制补码运算符是一元运算符,具有"翻转"位效果。 |
(~A)将得到-61,即为1100 0011,2的补码形式,带符号的二进制数。 |
<< |
二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 |
A<<2将得到240,即为1111 0000 |
>> |
二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 |
A>>2将得到15,即为0000 1111 |
运算符实例:
请看下面的实例,了解 C++ 中所有可用的逻辑运算符,复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序即可。
#include <iostream>
using namespace std;
main()
{
unsigned int a = 60; // 60 = 0011 1100
unsigned int b = 13; // 13 = 0000 1101
int c = 0;
c = a & b; // 12 = 0000 1100
cout << "Line 1 - c 的值是 " << c << endl ;
c = a | b; // 61 = 0011 1101
cout << "Line 2 - c 的值是 " << c << endl ;
c = a ^ b; // 49 = 0011 0001
cout << "Line 3 - c 的值是 " << c << endl ;
c = ~a; // -61 = 1100 0011
cout << "Line 4 - c 的值是 " << c << endl ;
c = a << 2; // 240 = 1111 0000
cout << "Line 5 - c 的值是 " << c << endl ;
c = a >> 2; // 15 = 0000 1111
cout << "Line 6 - c 的值是 " << c << endl ;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - c 的值是 12
Line 2 - c 的值是 61
Line 3 - c 的值是 49
Line 4 - c 的值是 -61
Line 5 - c 的值是 240
Line 6 - c 的值是 15
五、赋值运算符
下表列出了 C++ 支持的赋值运算符:
运算符 |
描述 |
实例 |
---|---|---|
= |
简单的赋值运算符,把右边操作数的值赋给左边操作数 |
C=A+B将把A+B的值赋给C |
+= |
加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 |
C+=A相当于C=C+A |
-= |
减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 |
C-=A相当于C=C-A |
*= |
乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 |
C=A相当于C=CA |
/= |
除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 |
C/=A相当于C=C/A |
%= |
求模且赋值运算符,求两个操作数的模赋值给左边操作数 |
C%=A相当于C=C%A |
<<= |
左移且赋值运算符 |
C<<=2等同于C=C<<2 |
>>= |
右移且赋值运算符 |
C>>=2等同于C=C>>2 |
&= |
按位与且赋值运算符 |
C&=2等同于C=C&2 |
^= |
按位异或且赋值运算符 |
C^=2等同于C=C^2 |
|= |
按位或且赋值运算符 |
C|=2等同于C=C|2 |
赋值运算符实例:
请看下面的实例,了解 C++ 中所有可用的赋值运算符,复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序即可。
#include <iostream>
using namespace std;
main()
{
int a = 21;
int c ;
c = a;
cout << "Line 1 - = 运算符实例,c 的值 = : " <<c<< endl ;
c += a;
cout << "Line 2 - += 运算符实例,c 的值 = : " <<c<< endl ;
c -= a;
cout << "Line 3 - -= 运算符实例,c 的值 = : " <<c<< endl ;
c *= a;
cout << "Line 4 - *= 运算符实例,c 的值 = : " <<c<< endl ;
c /= a;
cout << "Line 5 - /= 运算符实例,c 的值 = : " <<c<< endl ;
c = 200;
c %= a;
cout << "Line 6 - %= 运算符实例,c 的值 = : " <<c<< endl ;
c <<= 2;
cout << "Line 7 - <<= 运算符实例,c 的值 = : " <<c<< endl ;
c >>= 2;
cout << "Line 8 - >>= 运算符实例,c 的值 = : " <<c<< endl ;
c &= 2;
cout << "Line 9 - &= 运算符实例,c 的值 = : " <<c<< endl ;
c ^= 2;
cout << "Line 10 - ^= 运算符实例,c 的值 = : " <<c<< endl ;
c |= 2;
cout << "Line 11 - |= 运算符实例,c 的值 = : " <<c<< endl ;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - = 运算符实例,c 的值 = 21
Line 2 - += 运算符实例,c 的值 = 42
Line 3 - -= 运算符实例,c 的值 = 21
Line 4 - *= 运算符实例,c 的值 = 441
Line 5 - /= 运算符实例,c 的值 = 21
Line 6 - %= 运算符实例,c 的值 = 11
Line 7 - <<= 运算符实例,c 的值 = 44
Line 8 - >>= 运算符实例,c 的值 = 11
Line 9 - &= 运算符实例,c 的值 = 2
Line 10 - ^= 运算符实例,c 的值 = 0
Line 11 - |= 运算符实例,c 的值 = 2
六、杂项运算符
下表列出了 C++ 支持的其他一些重要的杂项运算符。
运算符 |
描述 |
---|---|
sizeof |
sizeof运算符返回变量的大小。例如,sizeof(a)将返回4,其中a是整数。 |
Condition?X:Y |
条件运算符。如果Condition为真?则值为X:否则值为Y。 |
, |
逗号运算符会顺序执行一系列运算。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。 |
.(点)和->(箭头) |
成员运算符用于引用类、结构和共用体的成员。 |
Cast |
强制转换运算符把一种数据类型转换为另一种数据类型。例如,int(2.2000)将返回2。 |
& |
指针运算符&返回变量的地址。例如&a;将给出变量的实际地址。 |
* |
指针运算符*指向一个变量。例如,*var;将指向变量var。 |
杂项运算符实例:
请看下面的实例,了解 C++ 中运算符的优先级,复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序即可。
对比有括号和没有括号时的区别,这将产生不同的结果。因为 ()、 /、 * 和 + 有不同的优先级,高优先级的操作符将优先计算。
#include <iostream>
using namespace std;
main()
{
int a = 20;
int b = 10;
int c = 15;
int d = 5;
int e;
e = (a + b) * c / d; // ( 30 * 15 ) / 5
cout << "(a + b) * c / d 的值是 " << e << endl ;
e = ((a + b) * c) / d; // (30 * 15 ) / 5
cout << "((a + b) * c) / d 的值是 " << e << endl ;
e = (a + b) * (c / d); // (30) * (15/5)
cout << "(a + b) * (c / d) 的值是 " << e << endl ;
e = a + (b * c) / d; // 20 + (150/5)
cout << "a + (b * c) / d 的值是 " << e << endl ;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
(a + b) * c / d 的值是 90 ((a + b) * c) / d 的值是 90 (a + b) * (c / d) 的值是 90 a + (b * c) / d 的值是 50
下一篇: 玩转GLSL:探索运算符与表达式的力量
推荐阅读
-
使用 C++ 中的 OpenSSL 库对文件进行 AES 加密和解密。
-
C++ 中的异常处理机制 - 重新抛出异常
-
JavaScript Fetch API 接口在 Chromium c++ 代码中的实现(二)
-
STL 中的 Priority_queue - 深入分析 C++ 中优先队列的实现原理、核心功能和基本机制。
-
C++ 中指针和数组相关操作符的优先级
-
C++ 中的类型转换
-
双向链表中插入函数的 C++ 标准库实现。-示例 1:
-
Java 中的五种 I/O 模式详解--五、异步 I/O(Asynchronous I/O)
-
挂载在Linux中的作用及实现方法独到详解
-
详解Linux系统中的磁盘挂载和卸载过程,深入探讨挂载点、命令以及最佳实践