鱼C论坛

 找回密码
 立即注册
查看: 1375|回复: 4

[已解决]自增自减问题

[复制链接]
发表于 2020-2-18 22:44:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>
  2. void main ()
  3. {
  4.         int i=8;
  5.         printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--);
  6.        
  7. }
复制代码

4.PNG
看了小甲鱼的视频,自己动手试了下,使用一个printf输出自增自减,
我理解的是所有的i自增自减以后才输出,但是第二个为什么会是7,不应该是8吗,
有没有朋友帮我解答下,详细点
最佳答案
2020-2-19 15:10:27
先看前提知识,再看步骤:
注:不同的编译器++ -- 放在一起运算的方式也不相同的,得到的值自然也就不同;道理差不多。所以一般都不会这么用。
幻灯片1.PNG

幻灯片2.PNG

幻灯片3.PNG

幻灯片4.PNG

幻灯片5.PNG

幻灯片6.PNG

幻灯片7.PNG

幻灯片8.PNG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-18 23:57:02 | 显示全部楼层
这个问题前几天见到过
你可以在这个帖子里看我的回答。
https://fishc.com.cn/forum.php?m ... 919&pid=4343099

看懂了的话可以选个最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-19 00:00:36 | 显示全部楼层
又是这类问题,对于这类问题不管输出了什么样的结果,都是错误的,因为这样的代码标准未定义,编译器可以随意发挥(真的是随意发挥,好好理解随意发挥这4个字),不同的编译器可能会有不同的结果,即使是同一个编译器,用了不同的选项也有可能会得到不同的结果,如果编译器输出了6个0,你也不能抱怨,因为你的代码行为未定义,编译器完全可以输出6个0以表示对你程序的抱怨,不过好像没有编译器这样做

有的编译器是把这一行中所有的前缀 ++ -- 全部运行完,然后输出结果,然后再继续运算后缀 ++ --
也有的编译器真的是从右到左,遇到一个算一个


  1. int a = 10;
  2. printf("%d %d %d\n", --a, --a, --a);
复制代码


编译器有可能输出 7 7 7
也有可能是 7 8 9
或者输出 9 8 7 (这个的可能性不大,不过并不是不能,虽然我没有见过输出这个结果的编译器,我见过前两个的,就是vs系列和gcc系列)
就算是输出了 0 0 0 也行,因为这样的代码行为未定义,不同的编译器会给出不同的结果

再一次说明,对于这类问题,编译器可以随意发挥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-19 00:12:50 | 显示全部楼层


  1.           printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--);
  2. 00412D3F 8B 45 FC             mov         eax,dword ptr [ebp-4]     //ebp-4就是i=8
  3. 00412D42 F7 D8                neg         eax                      //-8
  4. 00412D44 89 45 F8             mov         dword ptr [ebp-8],eax
  5. 00412D47 8B 4D F8             mov         ecx,dword ptr [ebp-8]
  6. 00412D4A 51                   push        ecx                      // ecx=eax=-8 倒数第一个数
  7. 00412D4B 8B 55 FC             mov         edx,dword ptr [ebp-4]
  8. 00412D4E F7 DA                neg         edx                     //-8
  9. 00412D50 89 55 F4             mov         dword ptr [ebp-0Ch],edx
  10. 00412D53 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]
  11. 00412D56 50                   push        eax                      //eax=edx=-8  倒数第二个数
  12. 00412D57 8B 4D FC             mov         ecx,dword ptr [ebp-4]
  13. 00412D5A 89 4D F0             mov         dword ptr [ebp-10h],ecx
  14. 00412D5D 8B 55 F0             mov         edx,dword ptr [ebp-10h]
  15. 00412D60 52                   push        edx                      //edx=ecx=8   倒数第三个数
  16. 00412D61 8B 45 FC             mov         eax,dword ptr [ebp-4]   
  17. 00412D64 89 45 EC             mov         dword ptr [ebp-14h],eax
  18. 00412D67 8B 4D EC             mov         ecx,dword ptr [ebp-14h]
  19. 00412D6A 51                   push        ecx                      //ecx=eax=8   倒数第四个数
  20. 00412D6B 8B 55 FC             mov         edx,dword ptr [ebp-4]    //edx=ebp-4=8
  21. 00412D6E 83 EA 01             sub         edx,1                   //edx=edx-1=7
  22. 00412D71 89 55 FC             mov         dword ptr [ebp-4],edx   //ebp-4=edx=7
  23. 00412D74 8B 45 FC             mov         eax,dword ptr [ebp-4]
  24. 00412D77 50                   push        eax                      //eax=edx=7    倒数第五个数 你所关心的
  25. 00412D78 8B 4D FC             mov         ecx,dword ptr [ebp-4]   //ecx=ebp-4=7
  26. 00412D7B 83 C1 01             add         ecx,1                   //ecx=ecx+1=8
  27. 00412D7E 89 4D FC             mov         dword ptr [ebp-4],ecx    //ecx=ebp-4=8
  28. 00412D81 8B 55 FC             mov         edx,dword ptr [ebp-4]   //edx=ebp-4=8
  29. 00412D84 52                   push        edx                      //edx=8       倒数第六个数
  30. 00412D85 68 B4 A1 42 00       push        offset string "%d\n%d\n%d\n%d\n%d\n%d\n" (0042a1b4)
  31. 00412D8A 8B 45 FC             mov         eax,dword ptr [ebp-4]
  32. 00412D8D 83 C0 01             add         eax,1
  33. 00412D90 89 45 FC             mov         dword ptr [ebp-4],eax
  34. 00412D93 8B 4D FC             mov         ecx,dword ptr [ebp-4]
  35. 00412D96 83 E9 01             sub         ecx,1
  36. 00412D99 89 4D FC             mov         dword ptr [ebp-4],ecx
  37. 00412D9C 8B 55 FC             mov         edx,dword ptr [ebp-4]
  38. 00412D9F 83 C2 01             add         edx,1
  39. 00412DA2 89 55 FC             mov         dword ptr [ebp-4],edx
  40. 00412DA5 8B 45 FC             mov         eax,dword ptr [ebp-4]
  41. 00412DA8 83 E8 01             sub         eax,1
  42. 00412DAB 89 45 FC             mov         dword ptr [ebp-4],eax
  43. 00412DAE E8 9D E5 FE FF       call        printf (00401350)
  44. 00412DB3 83 C4 1C             add         esp,1Ch                 //1Ch=28d 28/4(字节)=7个,这个call被压了7个参数,你数数看 再加上 push  offset string"%d\n%d\n%d\n%d\n%d\n%d\n" (0042a1b4)

复制代码

你看下反汇编,看注释
我个人的建议,++和--不要乱用,不然容易出问题的,不同的编译器处理起来也不同的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-19 15:10:27 | 显示全部楼层    本楼为最佳答案   
先看前提知识,再看步骤:
注:不同的编译器++ -- 放在一起运算的方式也不相同的,得到的值自然也就不同;道理差不多。所以一般都不会这么用。
幻灯片1.PNG

幻灯片2.PNG

幻灯片3.PNG

幻灯片4.PNG

幻灯片5.PNG

幻灯片6.PNG

幻灯片7.PNG

幻灯片8.PNG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-13 10:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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