后续有时间再继续研究
基础概念:i++是先赋值再运算,++i是先运算后赋值
问题来源于昨日对一个问答问题的回答,本以为就是简单的i++和++i的一个运算,结果发现还真是有点出乎意料
源代码:
#include <iostream>
using namespace std;
int main() {
int i = 3;
int p = (i++) + (i++) + (i++);
cout<<i<< " "<< p<<endl;
int q = (i++) + (++i) + (i++);
cout <<i<<" " << q<<endl;
int m = (++i) + (++i) + (i++);
cout<<i<< " "<<m<<endl;
return 0;
}
大家也可以先自己猜一下,运行结果应该是多少
实际本地测试下来,居然发现有三个运行结果:
分别是:
第一种情况
6 12
9 22
12 33
第二种情况
6 12
9 22
12 32
第三种情况
4 9
5 12
6 15
可能还会有其他的结果类型,当时看到这个结果后也是百思不得其解,直到看到大佬的回答才明白问题所在
i=1,为什么 (++i)+(++i)=6? - 知乎用户的回答 - 知乎 https://www.zhihu.com/question/347864795/answer/1699372384
以下内容引用自知乎上文大佬:
++i,如果单独写成一个语句,等同鱼i=i+1。我想这个应该没有人有问题。
但是其实这里应该是有问题的,特别是新手。对于新手来说,如果没有意识到这里的问题,那么就很可能在上面那个题目当中翻车。
什么问题呢?
也就是说,程序当中的表达式,并不是完全等同于数学公式。因此,不能单纯以数学的理念去理解它。
程序当中的i=i+1,其实应该理解为:从一个名叫i的地方(内存空间)取出一个数,将其加1,然后放入名叫i的地方。
也就是,程序当中的表达式,其实只是一系列语句(statement)的简写。i=i+1写成完整语句,其实是:
- load i -> 某CPU寄存器
- 将该寄存器内容+1
- save该寄存器内容 -> i
所以,(++i)+(++i)的意思其实是:
- load i -> 某CPU寄存器 (第一个括号
- 将该寄存器内容+1
- save该寄存器内容 -> i
- load i -> 某CPU寄存器 (第二个括号
- 将该寄存器内容+1
- save该寄存器内容 -> i
- load i -> 某
CPU寄存器(两个括号之间 - load i -> 另一个CPU寄存器
- 将两个寄存器内容相加
(但是注意虽然上面编了序号,但是1-3和4-6之间其实是并列关系,并非要按照序号顺序执行。7和8也是并列关系,可以按任何顺序执行。而这种执行的顺就是导致这个问题是个UB问题的原因)
这样就应该没有人还是认为结果一定是4了吧。
新手掉坑里的原因就在于,把程序当中的表达式当作数学式子,把其中的字母当作未知数
而理解表达式并不等同于数学式子,变量也不等同于未知数
看来以后 写代码还是不能图省事啊,能多写几行就多写几行吧,不然实际项目中如果出现类似这种bug可真让人头疼