dengshuang
V2EX  ›  编程

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

  •  
  •   dengshuang · Oct 11, 2018 · 4548 views
    This topic created in 2945 days ago, the information mentioned may be changed or developed.
    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 replies  •  2018-11-18 16:42:24 +08:00
    dengshuang
    dengshuang
    OP
    Oct 11, 2018
    1
    环境
    ```
    debian9.5 64 位
    gcc 6.3.0
    ```
    minami
    minami
    Oct 11, 2018❤️1
    2
    编译器已经很累了,它只想老老实实做优化,不想再和谭浩强玩了,你关心过它的感受吗?没有,你只关心你的 C 语言成绩
    正经点说,研究这个没啥意义,你可以反编译看看汇编代码是什么样的。
    misaka19000
    misaka19000
    Oct 11, 2018❤️1
    3
    第一个:
    (i++)+(i++)
    左边的值为 1,右边的值为 2,1 + 2 = 3
    第二个:
    (++i)+(++i)
    我算出来 b 是 5,不知道为什么你算得是 6
    seeker
    seeker
    Oct 11, 2018
    4
    b=(++i)+(++i)
    从结果强行猜编译后可能是这样的:
    i = i + 1 // 计算 ++i
    i = i + 1 // 计算又一个 ++ i
    int x = i // 赋值 1
    int y = i // 赋值 2
    b = x + y //最终结果
    真实情况可以看看汇编咋回事

    PS. 没人会这样写代码
    hobochen
    hobochen
    Oct 11, 2018 via Android❤️6
    5
    我觉得 gcc 要提供这样的功能,出现未定义行为自动格式化所有硬盘
    imkuang
    imkuang
    Oct 11, 2018 via Android
    6
    刚刚运行了一下,我算出来是 b=5
    dengshuang
    dengshuang
    OP
    Oct 11, 2018
    7
    @misaka19000 看到你的结果,我就安心了。跟编译器有关
    crab
    crab
    Oct 11, 2018
    8
    这种看汇编吧,但别写这种和自己过不去的。知道 i++和++i 就行
    innoink
    innoink
    Oct 11, 2018 via Android
    9
    sequence point 了解一下
    innoink
    innoink
    Oct 11, 2018 via Android❤️1
    10
    要么不钻牛角尖
    要么去学标准做语言律师
    要么看汇编面向实际
    misaka19000
    misaka19000
    Oct 11, 2018
    11
    @xiri #6 为什么你的头像怎么萌(*╹▽╹*)
    seeker
    seeker
    Oct 11, 2018
    12
    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/
    imkuang
    imkuang
    Oct 11, 2018 via Android
    13
    @misaka19000 #11 你的头像也很萌啊

    顺便补充一下我 #6 计算结果的环境:clang 7.0.0 (不在电脑旁,在手机上的 Termux 里算的)
    innoink
    innoink
    Oct 11, 2018 via Android
    14
    @seeker sequence point 和优化并没有什么关系,这就是个 UB
    newtype0092
    newtype0092
    Oct 11, 2018
    15
    这不叫难题,这叫傻逼问题。。。
    adoui
    adoui
    Nov 18, 2018
    16
    b = (i++) + (i++);
    b = 1 + (2);
    前面的的括号中 i =1,然后+1,到第二个括号是 i = 2 了,然后 1+2 赋值给 b。++放后面是先用后加。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1734 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 17:06 · PVG 01:06 · LAX 09:06 · JFK 12:06
    ♥ Do have faith in what you're doing.