读书人

一个简单的C程序解决思路

发布时间: 2012-06-14 16:00:31 作者: rapoo

一个简单的C程序
include <stdio.h>
main(){
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d,%d,%d,%d",p,q,i,j);
} q的结果为什么是22,不是21

[解决办法]
与编译器有关。。。
[解决办法]
Undefined
[解决办法]
看反汇编!
[解决办法]
对于这些运算符产生的Side Effect,编译器可以任意选择各个Side Effect的作用顺序。
[解决办法]
这种问题只有在书本上可以看到,在实际的工程应用中是不会出现的,因为不同的编译器产生的结果会有所不同。
[解决办法]

探讨
include <stdio.h>
main(){
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d,%d,%d,%d",p,q,i,j);
} q的结果为什么是22,不是21

[解决办法]
q是22么,应该是24吧,先算++j,实际上是3个8相加了吧
[解决办法]
这个六个编译器把


[解决办法]
探讨

q是22么,应该是24吧,先算++j,实际上是3个8相加了吧

[解决办法]
LZ,真没必要纠结
这个不同的编译器,答案不同的
如果你要搞清楚你的编译器的规则
建议看反汇编,那里一步一步的计算过程
[解决办法]

int j=4;
int a = i++ + i++;
int b = ++j + ++j;
printf("%d, %d\n", a, b);
问题又来了,i++ + i++是先自增一次,相加,再自增,然后赋值呢,还是先相加赋值然后自增两次呢。另外,++j又将如何表现呢?
结果是:6,12
这下明白了,原来 i++的理解应该是执行完整个表达式的其他操作后,然后才自增,所以例子中的a=3+3=6;而后i再自增2次,i=5;相反,++j是先自增然后再参加其它运算,所以b=6+6=12.
到此,是否就彻底明了了呢?然后回到引子中的问题
[解决办法]
它应该是这样的,P=((++I)+(++i))+(++I)
[解决办法]
同意二楼,不同编译器运行效果可能不一样。
[解决办法]
让楼主弄得很艹计!我的输出的结果是15.24.8.8(vs2010英文旗舰版)!!!
[解决办法]
这个就是教学用的c语言
[解决办法]
月经贴
[解决办法]
vs2008的编译结果
也就是一个语句中的++计算,要到语句结束的时候,才会反映到相应的寄存器。

; 5 : int p=(i++)+(i++)+(i++);

movecx, DWORD PTR [edx]
leaeax, DWORD PTR [ecx+ecx*2]
addecx, 3
movDWORD PTR [edx], ecx

[解决办法]
不好意思,前面发错了。vs是24, 如果是21也能理解
22 确实不知道内部是怎么实现的。

; 5 : int p=(++j)+(++j)+(++j);

addDWORD PTR [eax], 3
moveax, DWORD PTR [eax]
leaeax, DWORD PTR [eax+eax*2]


[解决办法]
不同编译器的原因
[解决办法]
探讨


如果那老师出的题,问你老师答案,如果是哪本书出的,把书扔了,如果哪面试出的,不去也罢。。


[解决办法]
我的编译器报警告,然后没输出


[解决办法]
这个和编译器有关,不同的编译器有不同的结果。
[解决办法]
编译器编译是用树形结构进行编译的
22
/\
14 ++j(8)
/\
++j(6) ++j(7)树种每2个节点运算时,同样一个变量名的值只能是一种,所以J在这一层的值应该都为7
7+7+8=22
[解决办法]
补充一下由于第二层得到的是中间值14 所以和j++(8)运算时没有改变J的值相当于j++和14的和 而不是两个都带有j的变量相加
[解决办法]
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

不要写连自己也预测不了结果的代码!

[解决办法]
指针就是地址完全是句放屁的话,都是被大学课本忽悠了的孩子,你有了小妞的电话号码,但你不一定拥有小妞,指针无非是小妞的电话号,而地址是你要找的小妞,仅此而已。
[解决办法]

探讨
指针就是地址完全是句放屁的话,都是被大学课本忽悠了的孩子,你有了小妞的电话号码,但你不一定拥有小妞,指针无非是小妞的电话号,而地址是你要找的小妞,仅此而已。

[解决办法]
如果,你没写错的话,,就是那本书错了!!!
[解决办法]
没必要
[解决办法]
探讨

LZ,真没必要纠结
这个不同的编译器,答案不同的
如果你要搞清楚你的编译器的规则
建议看反汇编,那里一步一步的计算过程

[解决办法]
探讨

引用:
include <stdio.h>
main(){
int i=5,j=5,p,q;
p=(i++)+(i++)+(i++);
q=(++j)+(++j)+(++j);
printf("%d,%d,%d,%d",p,q,i,j);
} q的结果为什么是22,不是21


月经贴。。。。。
如果那老师出的题,问你老师答案,如果是哪本书出……

[解决办法]
自增运算符、自减运算符有副作用,得谨慎使用。因为不同的编译器对其的处理是不同的。
[解决办法]
一点都无意义的题目,正常人都不会出这样的题目,出题的人都不知道怎么想的?没有确定的答案!

读书人网 >C语言

热点推荐