练习C语言自增运算卡壳了

@Ta 10-30 19:46 970点击
看到一段代码,然后自己拿来跑了下
void main()
{
	int a = 0, b = 0;
	printf("%d,%d,%d \n",a++,++a, a++); //2 2 0  //2 3 0
	getchar();
}

按我自己的理解应该输出2 2 0,但是不明白为何输出的结果是2 3 0
欢迎发表自己的看法,看我自己能不能找出我哪里理解错了
回复列表(12)
  • 1
    000
    @Ta / 10-30 20:21

    php 的话是0 2 2...斗图专属版

  • 2
    Hik
    @Ta / 10-30 23:17
    萌新表示不懂c,难道是中间的a膨胀了??
  • 4
    @Ta / 10-31 19:50
    @Curtion,赞,收益颇多。
    结合文中的描述也对i++有了更清晰的认识
    -我认为“i++是先取i的值,用这个值代入表达式”才更简单明了
    以前我对它们的概念就是先参与运算再自增,对值得改变一直很模糊
    在i=i++哪儿卡了好一会儿,直到自己模拟了一下
      3.i=i++
      先取i得值代入表达式计算0+0=0
      再把i+1=1
      此处i的值应该被改变
    这时我再去看上面那句话才明白了他所说的是此处的i被改变是不合理的。

    但是,如果离开那上面那句概念,i本身是个变量,顺序执行后被修改这我认为这也应该是合理的

    不过,在跟过两种组合的汇编后感觉会带来不好确定的变数,理解起来也更复杂

    --所以不知道能否运用在一些加密过程增加理解难度

    综上,从简单明了的角度我还是认为前面的概念比较合理

    -临时所感,有错望指正
  • 5
    @Ta / 10-31 20:02
    @000,在Release中得到的值是1,1,0.
    现在对编译过程还不了解。。
    不过,看来这样定义的不同问题确实存在
  • 6
    000
    @Ta / 10-31 22:31

    @user,所以说编写易维护的代码才是首要的 不要直接使用++了 斗图专属版

  • 7
    @Ta / 10-31 22:59
    层主 @小杨 于 2019-10-31 23:01 删除了该楼层。
  • 8
    @Ta / 11-01 14:39
    只觉得应该是输出
    0 2 2
    a最终值为3
  • 9
    @Ta / 11-04 06:29
    @胖罗,c中函数参数都是从右往左开始计算的,原因是啥我也忘了。至于最终值,在看了release版后,才认为更合理,两种符号在同一语句中最终结果就是+1。

    以前想明白调试模式下自增的过程原因,现在回头看就显得没有意义
  • 10
    @Ta / 11-04 07:06

    @user,看起来结果跟编译器的代码生成方式有关。我用GCC 5.4编译这个代码,无论优化等级开到多少,结果都是2,3,0
    -O0是没有任何优化(相当于Debug模式),-O3是最高等级优化。

    # gcc -O0 main.c -o main; ./main
    2,3,0
    # gcc -O1 main.c -o main; ./main
    2,3,0
    # gcc -O2 main.c -o main; ./main
    2,3,0
    # gcc -O3 main.c -o main; ./main
    2,3,0
    # gcc --version
    gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
    Copyright (C) 2015 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  • 11
    @Ta / 11-04 07:57

    -O0优化下生成的汇编代码(Intel语法):

    # gcc -O0 -c -g main.c; objdump -S -M intel ./main.o
    
    ./main.o:     file format elf64-x86-64
    
    Disassembly of section .text:
    
    0000000000000000 <main>:
    #include <stdio.h>
    void main()
    {
       0:   55                      push   rbp
       1:   48 89 e5                mov    rbp,rsp
       4:   48 83 ec 10             sub    rsp,0x10
        int a = 0, b = 0;
       8:   c7 45 f8 00 00 00 00    mov    DWORD PTR [rbp-0x8],0x0
       f:   c7 45 fc 00 00 00 00    mov    DWORD PTR [rbp-0x4],0x0
        printf("%d,%d,%d \n",a++,++a, a++); //2 2 0  //2 3 0
      16:   8b 55 f8                mov    edx,DWORD PTR [rbp-0x8]
      19:   8d 42 01                lea    eax,[rdx+0x1]
      1c:   89 45 f8                mov    DWORD PTR [rbp-0x8],eax
      1f:   83 45 f8 01             add    DWORD PTR [rbp-0x8],0x1
      23:   8b 45 f8                mov    eax,DWORD PTR [rbp-0x8]
      26:   8d 48 01                lea    ecx,[rax+0x1]
      29:   89 4d f8                mov    DWORD PTR [rbp-0x8],ecx
      2c:   8b 75 f8                mov    esi,DWORD PTR [rbp-0x8]
      2f:   89 d1                   mov    ecx,edx
      31:   89 f2                   mov    edx,esi
      33:   89 c6                   mov    esi,eax
      35:   bf 00 00 00 00          mov    edi,0x0
      3a:   b8 00 00 00 00          mov    eax,0x0
      3f:   e8 00 00 00 00          call   44 <main+0x44>
    }
      44:   90                      nop
      45:   c9                      leave
      46:   c3                      ret
  • 12
    @Ta / 11-06 23:01
    @老虎会游泳,嗯,我前几天还在想GCC 中该如何实现VS 里的release模式,现在明白了。
添加新回复
回复需要登录

[聊天-公共聊天室] 方哥:@寻梦xunm,鸡佬,捏好!小尾巴华为Mate30 X Max基佬版