一旦引入变量和常量,我们就可以开始使用运算符对它们进行操作。以下是运算符的完整列表。在这一点上,可能没有必要知道所有这些,但这里列出了它们作为参考。
1.赋值运算符(=)
赋值运算符为变量赋值。
x = 1;
此语句将整数值分配给变量 。赋值操作始终从右到左进行,而不是相反:1
x
x = y;
此语句将变量 中包含的值分配给变量。执行此语句时的值将丢失,并替换为 的值
例:
// assignment operator
#include <iostream>
using namespace std;
int main ()
{
int a, b; // a:?, b:?
a = 10; // a:10, b:?
b = 4; // a:10, b:4
a = b; // a:4, b:4
b = 7; // a:4, b:7
cout << "a:";
cout << a;
cout << " b:";
cout << b;
}
该程序在屏幕上打印 和 (分别为 4 和 7) 的最终值。请注意,即使我们之前声明了 的最终修改,也不受 的影响。
赋值操作是可以计算的表达式。这意味着赋值本身有一个值,对于基本类型,此值是在操作中赋值的值。例如:
y = 2 + (x = 5);
在此表达式中,赋值加 2 的结果和另一个赋值表达式的值(其本身的值为 5)。它大致相当于:
x = 5;
y = 2 + x;
x = y = z = 5;
它将 5 分配给所有三个变量,始终从右往左
2.算数运算符(+, -, *, /, %)
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 划分 |
% | 模 |
加法、减法、乘法和除法运算从字面上对应于它们各自的数学运算符。最后一个是取模运算符,由百分号 表示,给出两个值除法的余数。例如:
x = 11 % 3;
结果包含值 2 的变量,因为将 11 除以 3 得到 3,余数为 2。
3.复合赋值(+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)
复合赋值运算符通过对变量执行操作来修改变量的当前值。它们等效于将操作的结果分配给第一个操作数:
表达 | 相当于... |
---|---|
y += x; | y = y + x; |
x -= 5; | x = x - 5; |
x /= y; | x = x / y; |
price *= units + 1; | price = price * (units+1); |
例:
// compound assignment operators
#include <iostream>
using namespace std;
int main ()
{
int a, b=3;
a = b;
a+=2; // equivalent to a=a+2
cout << a;
}
4.递增和递减(++, --)
有些表达式可以进一步缩短:增加运算符 () 和减少运算符 () 将存储在变量中的值增加或减少一个。它们分别等效于 和 。因此:
++x;
x+=1;
x=x+1;
在功能上都是等效的;他们三个的值增加了一个。
5.关系运算符和比较运算符 ( ==, !=, >, <, >=, <= )
可以使用关系运算符和相等运算符比较两个表达式。例如,要知道两个值是否相等,或者一个值是否大于另一个值。
运算符 | 描述 |
---|---|
== | 等于 |
!= | 不等于 |
< | 小于 |
> | 大于 |
<= | 小于或等于 |
>= | 大于或等于 |
例:
(7 == 5)
(5 > 4)
(3 != 2)
(6 >= 6)
(5 < 5)
6.逻辑运算符 ( !, &&, || )
运算符是布尔运算 NOT 的C++运算符。它只有一个操作数,在其右侧,并反转它,如果它的操作数是,如果它的操作数是,则产生。基本上,它返回计算其操作数的相反布尔值。
例:
!(5 == 5) // 计算结果为false,因为它右边的表达式(5 == 5)为真
!(6 <= 4) // 计算结果为真,因为(6 <= 4)将为假
!true // 结果为false
!false // 求值为true
逻辑运算符 和 在计算两个表达式以获得单个关系结果时使用。运算符对应于布尔逻辑运算 AND,如果其两个操作数都是 ,则生成,否则。以下面板显示了运算符计算表达式的结果:
&&运算符(和) | ||
---|---|---|
a | b | a && b |
true | true | true |
true | false | false |
false | true | false |
false | false | false |
该运算符对应于布尔逻辑运算 OR,如果其任一操作数为 ,则产生 ,因此仅当两个操作数都为假时才为假。以下是以下可能的结果:
||运算符(或) | ||
---|---|---|
a | b | a || b |
true | true | true |
true | false | true |
false | true | true |
false | false | false |
使用逻辑运算符时,C++只从左到右计算必要的内容以得出组合的关系结果,而忽略其余部分。因此,在最后一个示例 () 中,C++首先计算是否为 ,如果是,则从不检查是否为 。这称为短路评估,对于以下运算符的工作方式如下:
运算符 | 短路 |
---|---|
&& | 如果左侧表达式为 ,则组合结果为 (从不计算右侧表达式)。false false |
|| | 如果左侧表达式为 ,则组合结果为 (从不计算右侧表达式)。true true |
当右侧表达式有副作用(例如更改值)时,这一点最为重要:
if ( (i<10) && (++i<n) ) { /*...*/ } // 注意,条件增加I
7.条件三元运算符 ( ?)
条件运算符计算表达式,如果该表达式的计算结果为 ,则返回一个值,如果表达式的计算结果为 。它的语法是:
7==5 ? 4 : 3 // 结果是3,因为7不等于5。
7==5+2 ? 4 : 3 // 结果是4,因为7等于5+2。
5>3 ? a : b // 等于a的值,因为5大于3。
a>b ? a : b // 求值为a或b中较大的值。
例:
// conditional operator
#include <iostream>
using namespace std;
int main ()
{
int a,b,c;
a=2;
b=7;
c = (a>b) ? a : b;
cout << c << '\n';
}
在此示例中,为 2 且为 7,因此被计算的表达式 () 不是 ,因此在问号之后指定的第一个值被丢弃,取而代之的是第二个值(冒号之后的值)(值为 7)。
8.逗号运算符 ( , )
逗号运算符 () 用于分隔包含的两个或多个表达式,其中只有一个表达式。当必须为表达式集计算值时,仅考虑最右侧的表达式。
a = (b=3, b+2);
将首先将值 3 分配给 ,然后分配给变量 。因此,最后,变量将包含值 5,而变量将包含值 3。
9.按位运算符 ( &, |, ^, ~, <<, >> )
按位运算符会根据表示其存储的值的位模式来修改变量。
运算符 | 等效于 | 描述 |
---|---|---|
& | AND | 按位和 |
| | OR | 按位包含 OR |
^ | XOR | 按位独占或 |
~ | NOT | 一元补码(位反转) |
<< | SHL | 向左移动位 |
>> | SHR | 向右移动位 |
10.显式类型转换运算符
类型转换运算符允许将给定类型的值转换为另一种类型。在C++有几种方法可以做到这一点。从 C 语言继承而来的最简单的方法是在要转换的表达式之前加上括在括号 (()) 之间的新类型:
int i;
float f = 3.14;
i = (int) f;
前面的代码将浮点数转换为整数值 ();其余部分丢失。此处,类型转换运算符为 。在 C++ 中执行相同操作的另一种方法是在要由类型转换的表达式之前使用函数表示法,并将表达式括在括号之间:
i = int (f);
11.运算符的优先级
单个表达式可以有多个运算符。例如:
x = 5 + 7 % 2;
在C++中,上面的表达式总是将 6 分配给变量,因为运算符的优先级高于运算符,并且总是在前面求值。可以将部分表达式括在括号中,以覆盖此优先顺序,或明确说明预期效果。请注意差异:
x = 5 + (7 % 2); // x = 6 (和不加括号一样)
x = (5 + 7) % 2; // x = 0
从最高优先级到最低优先级,C++运算符按以下顺序进行评估:
水平 | 优先级组 | 运算符 | 描述 | 分组 |
---|---|---|---|---|
1 | 范围 | :: | 范围限定符 | 从左到右 |
2 | 后缀(一元) | ++ -- | 后缀递增/递减 | 从左到右 |
() | 功能形式 | |||
[] | 下标 | |||
. -> | 会员访问 | |||
3 | 前缀(一元) | ++ -- | 前缀递增/递减 | 从右到左 |
~ ! | 按位不/逻辑不 | |||
+ - | 一元前缀 | |||
& * | 引用/取消引用 | |||
new delete | 分配/取消分配 | |||
sizeof | 参数包 | |||
(type) | C型铸型 | |||
4 | 指针到成员 | .* ->* | 访问指针 | 从左到右 |
5 | 算术:缩放 | * / % | 乘法、除法、取模 | 从左到右 |
6 | 算术:加法 | + - | 加法、减法 | 从左到右 |
7 | 按位移位 | << >> | 左移,右移 | 从左到右 |
8 | 关系 | < > <= >= | 比较运算符 | 从左到右 |
9 | 平等 | == != | 平等/不平等 | 从左到右 |
10 | 和 | & | 按位和 | 从左到右 |
11 | 独家或 | ^ | 按位异或 | 从左到右 |
12 | 包含或 | | | 按位或 | 从左到右 |
13 | 连接 | && | 逻辑和 | 从左到右 |
14 | 分离 | || | 逻辑或 | 从左到右 |
15 | 赋值级表达式 | = *= /= %= += -= | 分配/复合分配 | 从右到左 |
?: | 条件运算符 | |||
16 | 测 序 | , | 逗号分隔符 | 从左到右 |
当表达式具有两个具有相同优先级的运算符时,分组将确定首先计算哪一个运算符:从左到右或从右到左。
将所有子语句括在括号中(即使是那些由于其优先级而不必要的子语句)可以提高代码的可读性。
@Neng