c 自增的难题,想不出头绪。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dengshuang
V2EX    编程

c 自增的难题,想不出头绪。

  •  
  •   dengshuang 2018-10-11 15:45:53 +08:00 3683 次点击
    这是一个创建于 2565 天前的主题,其中的信息可能已经有所发展或是发生改变。
    int main(){ int i=1,b; b=(i++)+(i++); //关键点 printf("this is i %d\n",i); printf("this is b %d\n",b); return 0; } 结果 this is i 3 this is b 3 

    i 等于 3,并不难想代码中有 2 次++操作。

    b 等于 3,可能要难想一点。

    b=(i++)+(i++)先计算表达式在自增

    (i++)+(i++)=1+2=3

    第一个括号先取值得到 1,在自增。 第二个括号先取值得到 2,在自增。


    上面是后缀符号,前缀符号,我还没搞明白。

    b=(i++)+(i++);改成b=(++i)+(++i);

    结果为

    this is i 3 this is b 6 

    我想来想去也不应该等于 6 啊! 正常逻辑应该是等于 5 啊!先自增在计算表达式!

    后来我又改成了 b=(++i)+1+(++i);`

    结果还是等于 6.

    改成了 b=(++i)+2+(++i);` 结果等于 7;这才说的通啊。。。

    16 条回复    2018-11-18 16:42:24 +08:00
    dengshuang
        1
    dengshuang  
    OP
       2018-10-11 15:46:28 +08:00
    环境
    ```
    debian9.5 64 位
    gcc 6.3.0
    ```
    minami
        2
    minami  
       2018-10-11 15:53:42 +08:00   1
    编译器已经很累了,它只想老老实实做优化,不想再和谭浩强玩了,你关心过它的感受吗?没有,你只关心你的 C 语言成绩
    正经点说,研究这个没啥意义,你可以反编译看看汇编代码是什么样的。
    misaka19000
        3
    misaka19000  
       2018-10-11 16:00:14 +08:00   1
    第一个:
    (i++)+(i++)
    左边的值为 1,右边的值为 2,1 + 2 = 3
    第二个:
    (++i)+(++i)
    我算出来 b 是 5,不知道为什么你算得是 6
    seeker
        4
    seeker  
       2018-10-11 16:01:57 +08:00
    b=(++i)+(++i)
    从结果强行猜编译后可能是这样的:
    i = i + 1 // 计算 ++i
    i = i + 1 // 计算又一个 ++ i
    int x = i // 赋值 1
    int y = i // 赋值 2
    b = x + y //最终结果
    真实情况可以看看汇编咋回事

    PS. 没人会这样写代码
    hobochen
        5
    hobochen  
       2018-10-11 16:03:20 +08:00 via Android   6
    我觉得 gcc 要提供这样的功能,出现未定义行为自动格式化所有硬盘
    xiri
        6
    xiri  
       2018-10-11 16:06:22 +08:00 via Android
    刚刚运行了一下,我算出来是 b=5
    dengshuang
        7
    dengshuang  
    OP
       2018-10-11 16:07:51 +08:00
    @misaka19000 看到你的结果,我就安心了。跟编译器有关
    crab
        8
    crab  
       2018-10-11 16:09:02 +08:00
    这种看汇编吧,但别写这种和自己过不去的。知道 i++和++i 就行
    innoink
        9
    innoink  
       2018-10-11 16:10:22 +08:00 via Android
    sequence point 了解一下
    innoink
        10
    innoink  
       2018-10-11 16:11:28 +08:00 via Android   1
    要么不钻牛角尖
    要么去学标准做语言律师
    要么看汇编面向实际
    misaka19000
        11
    misaka19000  
       2018-10-11 16:12:39 +08:00
    @xiri #6 为什么你的头像怎么萌(**)
    seeker
        12
    seeker  
       2018-10-11 16:17:41 +08:00
    b=(++i)+(++i)
    GCC 编译后是这样的,所以是 6,过程跟我猜的差不多,MSVC 和 Clang 编译出来的应该是结果为 5。楼主喜欢钻牛角尖的话可以试试,GCC 让他不要优化。
    mov DWORD PTR [rbp-20], edi
    mov DWORD PTR [rbp-4], 1
    add DWORD PTR [rbp-4], 1
    add DWORD PTR [rbp-4], 1
    mov eax, DWORD PTR [rbp-4]
    add eax, eax
    mov DWORD PTR [rbp-8], eax
    mov eax, DWORD PTR [rbp-8]
    我是用这个网站看汇编的:
    https://godbolt.org/
    xiri
        13
    xiri  
       2018-10-11 16:26:30 +08:00 via Android
    @misaka19000 #11 你的头像也很萌啊

    顺便补充一下我 #6 计算结果的环境:clang 7.0.0 (不在电脑旁,在手机上的 Termux 里算的)
    innoink
        14
    innoink  
       2018-10-11 16:29:14 +08:00 via Android
    @seeker sequence point 和优化并没有什么关系,这就是个 UB
    newtype0092
        15
    newtype0092  
       2018-10-11 16:34:46 +08:00
    这不叫难题,这叫傻逼问题。。。
    adoui
        16
    adoui  
       2018-11-18 16:42:24 +08:00
    b = (i++) + (i++);
    b = 1 + (2);
    前面的的括号中 i =1,然后+1,到第二个括号是 i = 2 了,然后 1+2 赋值给 b。++放后面是先用后加。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2573 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 07:53 PVG 15:53 LAX 00:53 JFK 03:53
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86