引入
我们都知道前置++是先加一、再使用,后置++是先使用后加1,你如果只知道这些那我感觉你没有正真了解他们?仔细看看下面程序,你感觉会输出什么
#include <iostream>
using namespace std;
int main() {
int a = 5, *p = &a;
a = (*p)++;
cout << (*p);
return 0;
}
如果按照我们学习的后置++先使用后加加的规则,那就是先把(*p)赋值给a,然后(*p) += 1,因为p一直指向a,所以a即*p最终就是6了。
实际输出是:在VS中输出6,用g++或gcc编译得到结果是5。VS中不知道做了什么操作,但从汇编语言、底层角度去分析的话,输出应该是5。这里就扒掉后置++的底裤,看看它到底干了什么。
后置++的真实面目(i++)
以i++
为例,实际上它完成了以下几个步骤的操作:
i
在底层先赋值给一个临时变量t
i = i + 1
- 这时返回临时变量
t
所以i++
这个表达式执行后我们实际上拿到的是临时变量t
的值,也就是i
加一之前的原始值,而且最终的i
也完成了自加。这就是为什么先使用后自增的原因了。
这时再来理解这个表达式a = i++
,其实是将临时变量(存着i
的原始值)的值赋值给了a,同时i
本身也完成了自增。
进一步看我们开始的程序中a = (*p)++
,实际上完成的操作步骤是:
- (*p)赋值给临时变量(值为5)。
- (*p) = (*p) + 1,即a = a + 1,此时a变成了6,(*p)也是6。
- 临时变量的值(其实就是(*p)++的返回值,也是原始(*p)的值,就是5)赋值给a,这就给人一种后置++先使用的感觉。这一赋值事大了,原本a在第2步实际上变成了6,这里又把原来的5给变回去了,此时a即(*p)的值都还是5。
所以在下面输出*p时输出了5,这里不得不提一下C++中后置++的重载,我们重载后置++时也是使用了一个临时变量,估计就是根据这个原理,使用我们重载的后置++在VS上运行时输出的也是5
想从汇编代码去理解可以点击这篇博客
前置++(++i)
前置++好理解,用不到临时变量,就是在原变量上加1再返回原变量