鱼C论坛

 找回密码
 立即注册
查看: 5209|回复: 5

自增自减运算符的小问题

[复制链接]
发表于 2013-2-11 12:22:15 | 显示全部楼层 |阅读模式
2鱼币
#include <stdio.h>
void main()
{
int i=8;
printf("i1=%d\n",i);
printf("i2=%d\n",-i++);
printf("i3=%d\n",i);
}

运行后i1=8,i2=-8,i3=9,我想问的是为什么i3=9 喃?
我想的是i1=8,那么到i2的时候,由于是同一优先级,又都是右结合性的,所以先运算自增运算符,但由于自增运算符在变量的后面,所以是先打出结果,再进行自增,又由于还有负号运算符,所以i2=-8,打出-8后,进行自增,那么应该是-8+1=-7啊,为什么i3=9了呢?负号哪儿去了?

最佳答案

查看完整内容

你在这里指定的是输出格式-i,并不是将-i赋值给全局变量int i,所以尽管你在这输出的时候是-8,但全局变量里的i值依然是8,并未改变,至于下面那个为什么输出是9,那自然是8+1=9了 。。 像楼上斑竹给出的那段反汇编代码,里面就说到了。在寄存器里存的值并不带符号。或许你可以理解成局部变量和全局变量之间的关系....它的++运算仅仅是针对于作为全局变量的i进行的。如果你很感兴趣这些问题,可以去看看一本叫做《C陷阱与缺陷》的 ...
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2013-2-11 12:22:16 | 显示全部楼层
你在这里指定的是输出格式-i,并不是将-i赋值给全局变量int i,所以尽管你在这输出的时候是-8,但全局变量里的i值依然是8,并未改变,至于下面那个为什么输出是9,那自然是8+1=9了 。。 像楼上斑竹给出的那段反汇编代码,里面就说到了。在寄存器里存的值并不带符号。或许你可以理解成局部变量和全局变量之间的关系....它的++运算仅仅是针对于作为全局变量的i进行的。如果你很感兴趣这些问题,可以去看看一本叫做《C陷阱与缺陷》的书,里面有很多类似这样的经典实例...
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-2-11 14:04:12 | 显示全部楼层
看下vs2010的反汇编代码吧!
可能就知道为什么i3的值是9了

  1.         int i=8;
  2. 002313CE  mov         dword ptr [i],8  //把8放入i的内存单元
  3.         printf("i1=%d\n",i);
  4. 002313D5  mov         esi,esp  
  5. 002313D7  mov         eax,dword ptr [i]  //把i储存单元的值放到eax中
  6. 002313DA  push        eax  
  7. 002313DB  push        offset string "i1=%d\n" (23574Ch)  
  8. 002313E0  call        dword ptr [__imp__printf (2382D4h)]  
  9. 002313E6  add         esp,8  
  10. 002313E9  cmp         esi,esp  
  11. 002313EB  call        @ILT+300(__RTC_CheckEsp) (231131h)  
  12.         printf("i2=%d\n",-i++);
  13. 002313F0  mov         eax,dword ptr [i]  ////把i储存单元的值放到eax中
  14. 002313F3  neg         eax  //这里并没有改变i地址处的值,只是把寄存器里的值做了取反操作!
  15. 002313F5  mov         dword ptr [ebp-0D0h],eax  
  16. 002313FB  mov         ecx,dword ptr [i]  //把i储存单元的值放到ecx中
  17. 002313FE  add         ecx,1  //ecx 加1
  18. 00231401  mov         dword ptr [i],ecx  //把ecx放入i的储存单元
  19. 00231404  mov         esi,esp  
  20. 00231406  mov         edx,dword ptr [ebp-0D0h]  
  21. 0023140C  push        edx  
  22. 0023140D  push        offset string "i2=%d\n" (235744h)  
  23. 00231412  call        dword ptr [__imp__printf (2382D4h)]  
  24. 00231418  add         esp,8  
  25. 0023141B  cmp         esi,esp  
  26. 0023141D  call        @ILT+300(__RTC_CheckEsp) (231131h)  
  27.         printf("i3=%d\n",i);
  28. 00231422  mov         esi,esp  
  29. 00231424  mov         eax,dword ptr [i]  //把i储存单元的值放到eax中
  30. 00231427  push        eax  
  31. 00231428  push        offset string "i3=%d\n" (23573Ch)  
  32. 0023142D  call        dword ptr [__imp__printf (2382D4h)]  
  33. 00231433  add         esp,8  
  34. 00231436  cmp         esi,esp  
  35. 00231438  call        @ILT+300(__RTC_CheckEsp) (231131h)  
  36. }
复制代码
所以i3等于9

评分

参与人数 1鱼币 +3 收起 理由
huaidisk + 3 虽然不明白,但还是好厉害。。^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-2-11 15:44:23 | 显示全部楼层
负号没有进行复制
-i只是返回了-8没有把i改变成-8
所以第二个printf()是-8
第三个是9
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-27 00:22:30 | 显示全部楼层
看到反汇编代码我就蒙了,
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-27 09:51:27 | 显示全部楼层
谢谢最佳答案的解释
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-8 10:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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