| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1640 人关注过本帖, 2 人收藏
标题:一道简单的C程序,但输出结果难解释,请高手回答
只看楼主 加入收藏
gxhzzhj
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2009-9-23
结帖率:0
收藏(2)
已结贴  问题点数:20 回复次数:16 
一道简单的C程序,但输出结果难解释,请高手回答
main()
{
 long x=32769;
 printf("%ld,%d\n",x,x);
 printf("%d,%ld\n",x,x);

 }
在TC中运行,输出结果为:
32769,-32767
-32767,-2147418112
第一句输出结果好解释和理解,但是第二句输出结果为什么是这样,请高手解释,我问了我们老师都无法解释清楚,谢谢!
搜索更多相关主题的帖子: 输出 解释 结果 
2009-09-23 09:11
UserYuH
Rank: 12Rank: 12Rank: 12
来 自:毅华
等 级:火箭侠
威 望:8
帖 子:720
专家分:3300
注 册:2009-8-10
收藏
得分:1 
程序代码:
main() 
{ 
long x=1,b=0x00020001; 
printf("%d,%ld\n",b,x);
}
运行结果:
1 65538
b十六进字:0x00020001  x十六进字:0x00000001
printf函数%d输出b的两个字节0x0001,到第二个%ld是输出四个字节,就把b没输出的两个字节和x的低两字节合为一起。
合成:0x00010002   这值刚好是:65538
输出格式不匹配,结果会乱掉。

努力—前进—变老—退休—入土
2009-09-23 13:41
暗留香
Rank: 2
等 级:论坛游民
帖 子:49
专家分:75
注 册:2009-9-4
收藏
得分:1 
对上面的补充。
感觉这是流的问题。
格式化输入输出是需要把值放入流中的。
如:
main()
{
int a[2],i;
scanf("%d",&a[0]);
scanf("%d",&a[1]);
printf("%d%d",a[0],a[1]);
}

你输入:1空格2回车
就完成赋值了......
你这样输入的时候,是把“1空格2回车”放入流中,然后把1赋值给a[0],但是流中还有值,遇到下面的格式化输入的时候就把2给了a[1].

你那个是格式化输出,输出数值后,流中还有数据,就保留大下次输出....
2009-09-23 17:42
wangcheng911
Rank: 2
等 级:论坛游民
帖 子:59
专家分:45
注 册:2009-9-23
收藏
得分:1 
#include<stdio.h>
#include<conio.h>
main()
{
long x=32769;
printf("%ld  %d\n",x,x);
printf("%d  %ld\n",x,x);
getch();
}
在devc++中结果是
32769 32769
32769 32769
很正常啊
2009-09-23 22:25
pgy
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:C
等 级:小飞侠
威 望:8
帖 子:1248
专家分:2329
注 册:2009-9-23
收藏
得分:0 
首先,printf函数是从右到左的计算输出表达式表,但输出的时候是按照输出格式字符的顺序输出,比如int x=1;printf("%d,%d",x,x-=1);输出结果是0,0;而不是0,1;而楼主程序中的2个printf是顺序结构,所以输出前的赋值计算顺序是第一行后一个x→第一行前一个x→第二行后一个x→第二行前一个x(也就是从右往左,从上往下的计算),但输出的时候是从左往右,从上往下计算。
OK,let's start!
先算第一行后一个x的值,就是把32769以%d的格式赋给x,因为32769超过了%d格式的数值范围,而32769对应两字节的二进制是1000 0000 0000 0001,而%d最多表示0111 1111 1111 1111,so,32769被计算机理解为1000 0000 0000 0001 ,最高位被理解为符号,1代表负号,然后计算机就以1000 0000 0000 0001为原码求反码求补码得出1111 1111 1111 1111。转换为十进制就-32767。
再算第一行第一个x的值,格式允许,直接得出32769。
然后计算第二行后一个x,此时要注意了,因为long是4字节,32769是0000 0000 0000 0000 1000 0000 0000 0001,我们之前用了后16位的数据,而前面的还有16个0去哪了呢?这就是3楼说的“流”的问题咯,流向了此时要计算的第二行后一个x的计算中了,第二行的后一个x变成了1000 0000 0000 0001 0000 0000 0000 0000计算发现,1000 0000 0000 0001 0000 0000 0000 0000的值又超出了long的数值范围,所以按照算第一个的思想算出了-2147418112。

哈哈,终于算完了,我自己懂了,and you?
这是我基于所学的知识的理解,如果有错,请看出来的高手一定要告诉我啊。thanks!

[ 本帖最后由 pgy 于 2009-9-23 23:47 编辑 ]

我可好玩啦...不信你玩玩^_^
2009-09-23 23:15
gxhzzhj
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2009-9-23
收藏
得分:0 
5楼的朋友您好!谢谢您的解答,但是我还是有疑问,还不懂,像你所说,那么为什么下面的程序:
main()
{
 long x=32769;
 printf("%d,%ld\n",x,x);

 }
在TC中,输出结果为:
-32767,-2147418112

现在是只有一行了,就没有涉及到前面的16位没有输出的情况了,要是像你这样解释的话,现在后一个x用%ld输出应该是32769啊,然后计算前一个x,用%d输出是-32767,但是结果后一个x输出为什么是:-2147418112,请给予答复,谢谢您和大家!
2009-09-24 10:34
gxhzzhj
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2009-9-23
收藏
得分:0 
我觉得2楼的解释比较有道理,谢谢大家!
2009-09-24 10:49
pgy
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:C
等 级:小飞侠
威 望:8
帖 子:1248
专家分:2329
注 册:2009-9-23
收藏
得分:1 
楼主,你按2楼的算法可以算出只有1个printf()与计算机结果一致的结果。但如果算2个printf(),一样算不出来。
2楼的算法是流出来的数据补向下一个数据,因为只有一行,只有一个流,但当有2行的时候,是按计算顺序流,还是按输出顺序流?
而且如果按照流出的数据补在前面的话,那最后一个x的值应该也是32769。
我、2、3楼的思想都是对的,肯定是因为“流”的关系,但究竟该怎么流啊?流向哪啊?一行和两行的“流”有区别吗?
我要去车站接人,你看到了麻烦算一下。我数据结构才刚开始看,这个“流”跟数据结构的存储结构有关系,只到该怎么算的大虾麻烦说下,接完人回来再算,闪~~~~

我可好玩啦...不信你玩玩^_^
2009-09-24 11:41
atom_09
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:92
专家分:141
注 册:2009-8-24
收藏
得分:1 
讨论这干吗。。
本来就不让你超界 你还要超界。
2009-09-24 13:08
暗留香
Rank: 2
等 级:论坛游民
帖 子:49
专家分:75
注 册:2009-9-4
收藏
得分:0 
4楼的:我不知道你怎么弄的.....我在TC中测试你的代码发现还是原来的值。

6楼的:printf还是按照从左到右处理的,不过这个从左到右是入栈的操作。后入的是最右的,那么先出堆
       栈被处理的反而是最右的。从而导致了printf("%d,%d",x,x-=1);中先计算x-=1。但这仅仅是计算X的值,每计算好
       一个函数的值后必须还有个入栈操作,保存当前值。那么又颠倒过来了,输出的时候就是从左向右了。
     

我在这也遇到了与pgy一样的困惑。感觉,每个printf都有清“流”的效果。如果我这样
 
main()
{
long x=32769;
printf("%d\n",x);
printf("%ld\n",x);  
}
反而看不出效果- -!
2009-09-27 06:53
快速回复:一道简单的C程序,但输出结果难解释,请高手回答
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026319 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved