鱼C论坛

 找回密码
 立即注册
查看: 3671|回复: 14

C语言自增自减始终搞不懂。

 关闭 [复制链接]
发表于 2012-3-17 18:20:42 | 显示全部楼层 |阅读模式
5鱼币
本帖最后由 ﹎罗宾〞 于 2012-3-17 18:27 编辑
#include <stdio.h>
void main()
{
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d,%d,%d,%d\n",p,q,i,j);
}


输出后,为什么是
15
22
8
8
???
不应该是  p=(5+5+5)+1(参与运算后+1)   q=(5+1)+(5+1)+(5+1)(加1后参与运算)嘛?
小弟刚学,求教程。

最佳答案

查看完整内容

4: int i=5,j=5,p,q; 0041139E C7 45 F8 05 00 00 00 mov dword ptr ,5 ;把5放进4字节内存单元,这里存储的就是变量i的值 004113A5 C7 45 EC 05 00 00 00 mov dword ptr [j],5 ;把5放进4字节内存单元[j],这里[j]存储的就是变量j的值 5: p=(i++)+(i++)+(i++); ;p=(i++)+(i++)+(i++) 执行的步骤其实是这样的 p=i+i+i; 再执行3次i++; 004113AC 8B 45 F8 mov eax,dwo ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-3-17 18:20:43 | 显示全部楼层
     4:     int i=5,j=5,p,q;
0041139E C7 45 F8 05 00 00 00 mov         dword ptr [i],5          ;把5放进4字节内存单元[i],这里[i]存储的就是变量i的值
004113A5 C7 45 EC 05 00 00 00 mov         dword ptr [j],5          ;把5放进4字节内存单元[j][i],这里[j]存储的就是变量j的值
     5:     p=(i++)+(i++)+(i++);                                ;p=(i++)+(i++)+(i++) 执行的步骤其实是这样的 p=i+i+i; 再执行3次i++;
004113AC 8B 45 F8             mov         eax,dword ptr [i]          ;从这里
004113AF 03 45 F8             add         eax,dword ptr [i]          ;
004113B2 03 45 F8             add         eax,dword ptr [i]          ;到这里就是 i+i+i 运算
004113B5 89 45 E0             mov         dword ptr [p],eax     ;将 i + i + i 运算的结果保存到,4字节内存单元[p],[p]就是变量p,所以打印出p的值是15
004113B8 8B 4D F8             mov         ecx,dword ptr [i]        ;从这里  
004113BB 83 C1 01             add         ecx,1  
004113BE 89 4D F8             mov         dword ptr [i],ecx  
004113C1 8B 55 F8             mov         edx,dword ptr [i]  
004113C4 83 C2 01             add         edx,1  
004113C7 89 55 F8             mov         dword ptr [i],edx  
004113CA 8B 45 F8             mov         eax,dword ptr [i]  
004113CD 83 C0 01             add         eax,1                  ;到这里,执行3次 i++; 所以i的值输出后为8
004113D0 89 45 F8             mov         dword ptr [i],eax  
     6:     q=(++j)+(++j)+(++j);
004113D3 8B 45 EC             mov         eax,dword ptr [j]          ;++j 表现的的行为和 i++ 是不同的
004113D6 83 C0 01             add         eax,1                  ;先把[j]存到eax,再把eax的值+1,然后再把eax的值放入[j]
004113D9 89 45 EC             mov         dword ptr [j],eax          ;执行到这里的时候j 已经等于6
004113DC 8B 4D EC             mov         ecx,dword ptr [j]          ;[j]放入ecx,你需要明白[j]已经等于6
004113DF 83 C1 01             add         ecx,1                  ;然后ecx+1,
004113E2 89 4D EC             mov         dword ptr [j],ecx          ;再把ecx放到[j],这是[j]已经等于7
004113E5 8B 55 EC             mov         edx,dword ptr [j]          ;[j]放入edx,你需要明白[j]已经等于7
004113E8 83 C2 01             add         edx,1                  ;然后edx+1,
004113EB 89 55 EC             mov         dword ptr [j],edx          ;再把edx放到[j],这是[j]已经等于8
004113EE 8B 45 EC             mov         eax,dword ptr [j]          ;从这里
004113F1 03 45 EC             add         eax,dword ptr [j]          ;
004113F4 03 45 EC             add         eax,dword ptr [j]          ; 到这里就是 q =j+j+j,由于这时候j已经等于8,所以q =24
004113F7 89 45 D4             mov         dword ptr [q],eax

总结:
p=(i++)+(i++)+(i++); 其实相当于 p = i+i+i; i++;i++;i++;
q=(++j)+(++j)+(++j); 其实相当于 j++;j++;j++; p=j+j+j;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-17 19:27:04 | 显示全部楼层
呵呵 一开始我认为输出是21呢 汗。。
后来认真想想 后  第一个是15 没有错。
第二个q=(++j)+(++j)+(++j)       等于22
是因为   第一次   ++j 先变成了6        第二次    在次++j 变成 7    注意此时j=7  第三步计算7+7=14  不然你可以  改成  q=(++j)+(++j); 看看是不是14   第四步 14+(++j)=22;      你可以试试  q=(++j)+(++j)+(++j)+(++j)  在次改成这样 看看是不是31                 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-17 21:03:32 | 显示全部楼层
本帖最后由 小楼 于 2012-3-17 21:10 编辑

p=(i++)+(i++)+(i++);  p=5+5+5  q=(++j)+(++j)+(++j); q=8+8+8
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-17 23:39:16 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-17 23:53:41 | 显示全部楼层
在同一个句子里面不要使用这么多的自增和自减,前缀自增就是先+1后执行,后缀自增就是先执行后+1,至于判定的地方,一般是在一个表达式后面的逗号或者是分号后面执行后缀自增。但是有的地方说不清楚,不同的系统和不同的编译器都不好说。
至于本体里面,q的值其实很不确定,我的系统用vc++6.0算出来的是22,但是有的可能是21,甚至24。在同一个语句里面预算一个变量两次自增以上就不好确定值了,因为你不知道系统是从左到右运算还是从右向左运算。
楼主尽量不要用这种方法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-3-18 14:44:34 | 显示全部楼层
湮汐 发表于 2012-3-17 23:53
在同一个句子里面不要使用这么多的自增和自减,前缀自增就是先+1后执行,后缀自增就是先执行后+1,至于判定 ...

视频上的一个例题呢。问下,这个是不是很重要的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-18 17:12:41 | 显示全部楼层
﹎罗宾〞 发表于 2012-3-18 14:44
视频上的一个例题呢。问下,这个是不是很重要的?

嗯,自加自减是蛮重要的,但是不好意思,我没有看视频,你把例题发一下吧!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-22 11:02:39 | 显示全部楼层
﹎罗宾〞 发表于 2012-3-18 14:44
视频上的一个例题呢。问下,这个是不是很重要的?

小甲鱼在视频上面说了,是编译器的问题。也希望大家不要那样用,在不同的编译器上面会有不同的结果。一个语句里面使用一个变量的多次自增自减,可读性差,而且还容易出错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-22 11:15:54 | 显示全部楼层
这个没有什么意思。。不要继续研究了。以后做项目写程序也不要写这种代码。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-22 14:06:36 | 显示全部楼层
各位注意:
首先,这个问题的答案是编译器相关的.
其次,它的问题并不在于"同一语句里使用了多个++,--之类有副作用的运算符"
而在于:"同一语句里对同一变量使用了多个++,--之类有副作用的运算符"
还有,3楼的,你帖汇编代码是没有意义的,这只能解释某中编译器是这样汇编C代码的,我换一种编译器,汇编结果就不一样了.
最后,这个题目的意义就在于让我们知道:不要写出这种代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-22 21:43:28 | 显示全部楼层
wAterLoo 发表于 2012-3-17 20:00
4:     int i=5,j=5,p,q;
0041139E C7 45 F8 05 00 00 00 mov         dword ptr ,5          ;把5放进4字节 ...

运行后q=22,但是你汇编出来的是24,是不是哪里错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-22 21:44:25 | 显示全部楼层
Mautuor 发表于 2012-3-22 21:43
运行后q=22,但是你汇编出来的是24,是不是哪里错了

vs2010 的结果是24
vc++ 的是 22
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-22 22:00:49 | 显示全部楼层
wAterLoo 发表于 2012-3-22 21:44
vs2010 的结果是24
vc++ 的是 22

看来这和编译系统有很大关系,以后使用得注意点,谢谢解答:lol
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-3-22 22:37:52 | 显示全部楼层
确实没啥研究的,根据编译器编译的不一样它结果就是不一样的,反成汇编是啥他就是啥~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-11 18:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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