记录一下i++和++i连加遇到的一些问题

后续有时间再继续研究

基础概念: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

可能还会有其他的结果类型,当时看到这个结果后也是百思不得其解,直到看到大佬的回答才明白问题所在

http://在C语言中,执行a=2;b=(++a)+(++a);之后b的结果为什么是8? - 知乎用户kcjSZe的回答 - 知乎 https://www.zhihu.com/question/39590451/answer/288933259


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写成完整语句,其实是:

  1. load i -> 某CPU寄存器
  2. 将该寄存器内容+1
  3. save该寄存器内容 -> i

所以,(++i)+(++i)的意思其实是:

  1. load i -> 某CPU寄存器 (第一个括号
  2. 将该寄存器内容+1
  3. save该寄存器内容 -> i
  4. load i -> 某CPU寄存器 (第二个括号
  5. 将该寄存器内容+1
  6. save该寄存器内容 -> i
  7. load i -> 某
    CPU寄存器(两个括号之间
  8. load i -> 另一个CPU寄存器
  9. 将两个寄存器内容相加

(但是注意虽然上面编了序号,但是1-3和4-6之间其实是并列关系,并非要按照序号顺序执行。7和8也是并列关系,可以按任何顺序执行。而这种执行的顺就是导致这个问题是个UB问题的原因)

这样就应该没有人还是认为结果一定是4了吧。

新手掉坑里的原因就在于,把程序当中的表达式当作数学式子,把其中的字母当作未知数

而理解表达式并不等同于数学式子,变量也不等同于未知数

看来以后 写代码还是不能图省事啊,能多写几行就多写几行吧,不然实际项目中如果出现类似这种bug可真让人头疼

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值