一道C语言题目


#include<stdio.h>
int main()
{
float x,y;
x=5;
y=3;
printf("x=%d y=%d\n",x,y);
return 0;
}

这个程序运行的结果是x=0 y=1075052544
我一直以为是随机的,不过好像不是这样,应该和存储结构有关,不知哪一位能够解释一下
如果把 float 改成 double 又是怎么样的呢

22 个解决方案

#1


数据存储结构问题
float格式的5存储为:0 10000001 01000000000000000000000
float格式的3存储为: 0 10000000 10000000000000000000000

#2


换成double的话,8个字节,后面的0更多了
不过不明白的是为什么这样算下来结果不对,即:

float格式的5存储为:0 10000001 01000000000000000000000 
float格式的3存储为: 0 10000000 10000000000000000000000
转换成4字节的int值结果和输出不对。。

#3


期待答案~~~~!

#4


#include <stdio.h > 
int main() 

float x,y; 
x=5; 
y=3; 
printf("x=%f y=%f\n",x,y); 
return 0; 

/*存储方式不同于整型*/

#5


晕!!!
x,y都是浮点型的,printf里面就不能用%d,要用%f啊

#6


是啊,你的float x,y; 
那么printf("x=%d y=%d\n",x,y); 错了
printf("x=%f y=%f\n",x,y); 才对

#7


个人认为这个和printf的实现有一定的关系

#8


lz问的是为什么,希望能得到原因解释,上面的几位回答等于没有说,谁都知道怎么改。

#9


肯定和printf内部实现有关系

#10


printf("x=%f y=%f\n",x,y);  

#11


学习观望!!

#12


以下分析基于PC,Windows XP SP2,Visual C++ 6.0。

先看看汇编码:

6:        x = 5;
0040E9C8 C7 45 FC 00 00 A0 40 mov         dword ptr [ebp-4],40A00000h
7:        y = 3;
0040E9CF C7 45 F8 00 00 40 40 mov         dword ptr [ebp-8],40400000h
8:        printf("x = %d, y = %d\n", x, y);
0040E9D6 D9 45 F8             fld         dword ptr [ebp-8]
0040E9D9 83 EC 08             sub         esp,8
0040E9DC DD 1C 24             fstp        qword ptr [esp]
0040E9DF D9 45 FC             fld         dword ptr [ebp-4]
0040E9E2 83 EC 08             sub         esp,8
0040E9E5 DD 1C 24             fstp        qword ptr [esp]
0040E9E8 68 1C 30 42 00       push        offset string "x = %d, y = %d\n" (0042301c)
0040E9ED E8 8E 26 FF FF       call        printf (00401080)

注意40A00000H和40400000H,它们是单精度的5.0和3.0。
(可以参考http://www.psc.edu/general/software/packages/ieee/ieee.html)

在第一个fstp指令,0012FF24处(我的机器上esp-8后的地址)被置成4008000000000000,注意,这已经是双精度的3.0了。
第二个fstp指令,0012FF1C处被置成4014000000000000,这是双精度的5.0。
上面两个fstp可以看成是函数调用前的压栈,先压的y,后压的x。

call printf的时候,从0012FF1C开始取x,y的值,但由于传递的是%d,所以只要取4byte就好,x取得00000000,y取得40140000。
这分别就是打印出来的0和1075052544。

以上是个人看法,供参考。

#13


12楼分析的还算透彻,我就不再说啦 ,不过想给大家说点建议,如果要学好编程,其实学一些汇编和了解计算机的存储结构是对学C很有帮助的!

#14


这个原因其实不用看汇编
这个问题出现和动态参数列表有关。由于是动态参数类别,无论语言和代码都无法决定后续的参数的类型是什么的。在赋值给va_list之后,实际上函数是通过一个无类型或者任意类型的指针而不是对象自己的实际指针类型来处理的

当printf格式化字符串时,他读到%d,就以为这是一个int型的数据,语法上的效果等价于把那个浮点数做如下转换*(int*)&x  :注意,这里不是隐式或者显式类型转换,而是仅仅纯粹的内存映射。这样实际上内存布局是float的变量被当作int来处理,由于float的内存布局和int完全不一样,导致输出的结果是不可预期的

因此对于任何动态参数列表的情况,你应该对参数做显式类型转换而不是依赖于隐式类型转换,这式因为隐式类型转换实际上根本不会做,printf只会“以为”他是个整型数,而不会以为他是浮点数再做转换。

#15


这样就对了printf("x=%d y=%d\n",(int)x,(int)y);

#16


数据存储结构问题,最好别这样用

#17


看了上述回复,觉得forestdb说的是正解,原来又转换成double型了。多谢forestdb。
楼主可以将分数给forestdb了

#18


#include <stdio.h > 
int main() 

float x,y; 
x=5; 
y=3; 
printf("x=%f y=%f\n",x,y);  //此处别把浮点类型的数据用整型表示,不然得出的结果会是0或未知数
return 0; 

#19


进来学习,大家分析的不错

#20


我来简化一下,
float 类型占用4个字节和int 类型相同,因此x=5;y=3;以后
float格式的5存储为:0 10000001 01000000000000000000000
float格式的3存储为: 0 10000000 10000000000000000000000
但是在计算机内浮点运算都是按照double计算的,因此printf("x=%d y=%d\n",x,y);需要调用x,y的值时候先转换成double入栈,然后由于传递的是%d,所以只要取4byte就好,这样就出现了楼主的结果。

#21


%d是整形方式输出,浮点数要用%f

#22


谢谢各位的解答了
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告