自增/自减运算符
自增和自减变量
变量的自增(加1)和自减(减1)都很常见,因此它们都有自己的运算符。
运算符 | 符号 | 使用形式 | 结果 |
---|---|---|---|
前缀自增 | ++ | ++x | x 加一,返回x |
前缀自减 | -- | --x | x 减一,返回x |
后缀自增 | ++ | x++ | 拷贝x,x加一,返回拷贝的值 |
后缀自减 | -- | x-- | 拷贝x,x减一,返回拷贝的值 |
请注意,每个运算符都有两个版本------前缀版本(运算符位于操作数之前)和后缀版本(运算符在操作数之后)。
前缀自增和自减
前缀增量/减量运算符非常简单。首先,操作数自增或自减,然后表达式计算为操作数的值。例如:
c++
#include <iostream>
int main() {
int x{8};
int y{++x};
std::cout << "x的值为"<<x<<"\n";
std::cout << "y的值为"<<y<<"\n";
}
输出结果为:
bash
x的值为9
y的值为9
后缀自增和自减
后缀自增/自减操作符更复杂。首先,复制操作数。然后自增或自减操作数(而不是副本)。最后,返回副本。例如:
c++
#include <iostream>
int main() {
int x{8};
int y{x++};
std::cout << "x的值为"<<x<<"\n";
std::cout << "y的值为"<<y<<"\n";
}
输出结果为
bash
x的值为9
y的值为8
解释
- 首先,创建x的临时副本,该副本从与
x{8}
相同的值开始。 - 然后,x从8增加到9。
- 然后返回x的副本(仍然具有值
8
),并将其分配给y。 - 然后丢弃临时副本。
- 因此,y以值8结束,x以值9结束。
代码拆解
int y{x++}
等价于
c++
//首先,创建x的临时副本,该副本从与`x{8}`相同的值开始。
int tmpx {x};
//然后,x从8增加到9。
x = x+1;
//然后返回x的副本(仍然具有值`8`),并将其分配给y。
int y {tmpx};
请注意,后缀版本需要更多的步骤,因此性能可能不如前缀版本。
更多示例
下面是另一个显示前缀和后缀版本之间差异的示例:
c++
#include <iostream>
int main()
{
int x { 8 };
int y { 9 };
//x = 8,y = 9
std::cout << x << ' ' << y << '\n';
//前缀自增 x = 9, 前缀自减 y=8
std::cout << ++x << ' ' << --y << '\n'; // 前缀
//变化后 x =9,y=8
std::cout << x << ' ' << y << '\n';
//后缀自增,打印x拷贝的临时副本,所以 x++ 打印为9,但x已经发生变化为10
//后缀自减,打印y拷贝的临时副本,所以 y-- 打印为8,但y已经发生变化为7
std::cout << x++ << ' ' << y-- << '\n'; // 后缀
//打印变化后的值 x = 10,y=7
std::cout << x << ' ' << y << '\n';
return 0;
}
输出结果为:
bash
8 9
9 8
9 8
9 8
10 7
前缀vs后缀的使用时机
在许多情况下,前缀和后缀操作符产生相同的行为:
c++
int main()
{
int x { 0 };
++x; // x加一变成1
x++; // x加一变成2
return 0;
}
在前缀或后缀版本的都可以使用情况下,最好使用前缀版本,因为前缀版本通常性能更好,并且不太可能引起意外。
注意后缀操作符产生临时副本的问题,在赋值时前缀操作符采用的是变化后的值,而后缀运算符是临时副本。