主要区别有两点
- ++i的返回值是i+1后的值,也就是先进行加法,然后返回。i++的返回值则是i。
- i++不能作为左值,而++i可以。
左值:可以放在赋值符=左边的变量,即在内存中有确定的存储地址,并且能够由用户改变其值的量。右值则是所有不是左值的表达式的值;左值相当于地址值,右值相当于数据值。
具体它们的实现函数如下
int& int::operator++() //这里返回的是一个引用形式,就是说函数返回值也可以作为一个左值使用
{//函数本身无参,意味着是在自身空间内增加1的
*this += 1; // 增加
return *this; // 取回值
}
//后缀形式:
const int int::operator++(int) //函数返回值是一个非左值型的,与前缀形式的差别所在。
{//函数带参,说明有另外的空间开辟
int oldValue = *this; // 取回值
++(*this); // 增加
return oldValue; // 返回被取回的值
}
观察其实现函数可知:
- i++依赖i++实现,举例i=3执行a=i++;之后a=3,i=4。i值在执行i++之后确实发生了改变,但是由于i++的返回值是旧值,所以a=3。
- ++i的返回值是一个具体的变量地址,并且这个地址是可以被用户重新改写的。符合左值的定义。而i++返回的只是oldValue,是一个数据值,并没有代表任何的地址值,因此就是右值,就像你不能&(3)一样。 ```cpp ++i = 1;//正确 i++ = 1; //错误
int i = 0; int ip = &(i++); //错误 int ip = &(++i); //正确
``
网上常会有类似这种解释:“
i = 3,
a = i++;`得到a的值等于3,可以视作先把i的值赋给a,然后再进行i+1的操作。“这样说其实是有失偏颇的,首先i++的运算优先级高于赋值,所以先进行I++,此时i的值已经等于4了,但是i++的返回值是oldValue,所以是3,所以a会被赋值为3。这样的解释才是正确的。
工作中i++和++i的相关问题还是不常遇到。不过遇到的时候,要是不熟悉左值右值的特性那估计也会很头疼。知乎上有个相关回答很赞同。