VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 419|回复: 13

[已解决]自增运算,(疾风有归途的问题)

[复制链接]
13_avatar_middle
最佳答案
0 
在线会员 发表于 2021-10-23 10:27:25 来自手机 | 显示全部楼层 |阅读模式
#include<iostream>
using namespace std;

int main()
{
    int i=3,j=3,a,b;
    a=(i++)+(i++)+(i++);
    b=(++j)+(++j)+(++j);
    cout <<a<< endl;
    cout <<b<< endl;
}
之前疾风同学问过这个问题,不过他b也和a一样,都是后加的,这个加在后面的确实好理解一点。
但因为好奇
所以我试了下这段,发现结果 自增运算,(疾风有归途的问题) b是16  这个b是16怎么来的又搞不明白了,就算是4+5+6,不也应该是15吗

(我在疾风同学帖子下面留言提出了这个疑问…但好像没人能看到…所以重发一个吧)
最佳答案
31_avatar_small
2021-10-24 12:53:05
这是非常有名的一道题,目的是理解前++后++,考试经常会碰到!
  1. #include<iostream>
  2. using namespace std;

  3. int main()
  4. {
  5.         int i = 3, j = 3, a, b;
  6.         a = (i++) + (i++) + (i++);        // a = 3 + 3 + 3
  7.         b = (++j) + (++j) + (++j);        // b = (j += 1, j += 1, j += 1) * 3
  8.         cout << a << endl;
  9.         cout << b << endl;
  10.         cout << i << endl;        // i 一共后 "++" 三次 == 6
  11.         cout << j << endl;        // j 一共前 "++" 三次 == 6

  12.         // 验证
  13.         int c = 3;
  14.         int d = (c += 1, c += 1, c += 1) * 3;
  15.         cout << d << endl;        // 最终 d == 18
  16. }
复制代码




上一篇:求助
下一篇:关于类的派生,我有一个问题,想问一下
86_avatar_middle
最佳答案
0 
在线会员 发表于 2021-10-24 14:36:22 | 显示全部楼层
本帖最后由 s1410224564 于 2021-10-24 16:24 编辑

结论:这问题其实跟编译器有关了,没啥好纠结的。

(++j)+(++j)+(++j)
=j +(++j)+(++j)        //j=4
=j + j +(++j)                //j=5
=j + j + j                                 //j=6
=6 + 6 + 6
=18
这是在vs2019的环境下mvsc编译器编译的,上面的运算顺序也是根据反汇编后的结果总结的。

我用g++编译器编译,结果是16,下面是b=(++j)+(++j)+(++j);这语句的反汇编的结果:
        add    DWORD PTR [rbp-0xc],0x1                        //j+1,j等于4
        add    DWORD PTR [rbp-0xc],0x1                        //j+1,j等于5

        //j + j 因为此时j=5,所以结果=10
        mov    eax,DWORD PTR [rbp-0xc]                       
        lea      edx,[rax+rax*1]                                       
       
        //j+1 ,然后将  j + 上面结果,所以等于6 + 10 =16
        add    DWORD PTR [rbp-0xc],0x1
        mov    eax,DWORD PTR [rbp-0xc]
        add    eax,edx
        mov    DWORD PTR [rbp-0x4],eax

运算顺序大概就是:
((++j)+(++j))+(++j)
=( j +(++j))+(++j)
=( j + j )+(++j)
=  10 +(++j)
=  10 + 6
=  16

点评

大佬牛逼,请收下我的膝盖  发表于 2021-10-24 18:40
赞一个  发表于 2021-10-24 18:39

评分

参与人数 1驿站币 +1 热心值 +1 收起 理由
00_avatar_small oyxbl + 1 + 1 赞一个!

查看全部评分

31_avatar_middle
最佳答案
53 
在线会员 发表于 2021-10-24 12:53:05 | 显示全部楼层    本楼为最佳答案   
bestAnswer
这是非常有名的一道题,目的是理解前++后++,考试经常会碰到!
  1. #include<iostream>
  2. using namespace std;

  3. int main()
  4. {
  5.         int i = 3, j = 3, a, b;
  6.         a = (i++) + (i++) + (i++);        // a = 3 + 3 + 3
  7.         b = (++j) + (++j) + (++j);        // b = (j += 1, j += 1, j += 1) * 3
  8.         cout << a << endl;
  9.         cout << b << endl;
  10.         cout << i << endl;        // i 一共后 "++" 三次 == 6
  11.         cout << j << endl;        // j 一共前 "++" 三次 == 6

  12.         // 验证
  13.         int c = 3;
  14.         int d = (c += 1, c += 1, c += 1) * 3;
  15.         cout << d << endl;        // 最终 d == 18
  16. }
复制代码

点评

赞一个  发表于 2021-10-24 18:37

评分

参与人数 1驿站币 +1 热心值 +1 收起 理由
00_avatar_small oyxbl + 1 + 1 赞一个!

查看全部评分

31_avatar_middle
最佳答案
53 
在线会员 发表于 2021-10-24 19:27:15 | 显示全部楼层
这道题主要是理解前++后++,涉及运算符优级相关知识,正常开发没人写这种代码,各家编译器实现的标准不一样就会导致运算结果不一样,但这不是这道题的关键,这种写法或者说风格,对于跨平台项目来说是存在很大的隐患的。

点评

本来我还纳闷两个编译器不同会有啥问题来着,隐约就只是觉得奇怪而且不妥,但又说不出来哪里不对。大佬一番话,让萌新如醍醐灌顶,连将来移植的问题都考虑进去了。看来以后写代码能写明白就得写的明白一点。  发表于 2021-10-25 00:05
00_avatar_middle
最佳答案
11 
在线会员 发表于 2021-10-23 13:57:02 | 显示全部楼层
不知道
单步调试应该能发现问题
自增运算,(疾风有归途的问题)
13_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-10-23 14:20:40 来自手机 | 显示全部楼层
oyxbl 发表于 2021-10-23 13:57
不知道
单步调试应该能发现问题

C的单步调试是哪个键,我才接触(      )
易语言的单步调试我倒是用过。
00_avatar_middle
最佳答案
11 
在线会员 发表于 2021-10-23 15:12:27 | 显示全部楼层
写意春秋 发表于 2021-10-23 14:20
C的单步调试是哪个键,我才接触(      )
易语言的单步调试我倒是用过。

od和dbg96

快捷键F8

需要了解汇编

https://www.zhihu.com/question/19811087

我怀疑你在灌水,,但是我没有证据

自增运算,(疾风有归途的问题)
13_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-10-23 15:14:56 来自手机 | 显示全部楼层
oyxbl 发表于 2021-10-23 15:12
od和dbg96

快捷键F8

……灌水怎么可能…我也是醉了……
43_avatar_middle
最佳答案
0 
在线会员 发表于 2021-10-23 21:04:56 | 显示全部楼层
为哈我把你这代码复制到vs2013中,结果和你们说的都不一样呢

#include<iostream>
using namespace std;

int main()
{
        int i = 3, j = 3, a, b;
        a = (i++) + (i++) + (i++);
        b = (++j) + (++j) + (++j);
        cout << a << endl;
        cout << b << endl;
        cout << i << endl;
        cout << j << endl;
}

结果是
9
18
6
6

评分

参与人数 1驿站币 +1 热心值 +1 收起 理由
00_avatar_small oyxbl + 1 + 1 反面典型,,这样写会被后辈打

查看全部评分

13_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2021-10-24 16:12:58 来自手机 | 显示全部楼层
s1410224564 发表于 2021-10-24 14:36
()的优先级 比 +的优先级高,所以先执行括号里的运算。
(++j)+(++j)+(++j)
=j +(++j)+(++j)         ...

你这样解释确实也非常到位,手动给赞!
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号-4 )|网站地图wx_jqr

GMT+8, 2021-11-30 01:49

Powered by CcTry.CoM

© 2009-2021 cctry.com

快速回复 返回顶部 返回列表