首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

C语言程序-诡谲的结果

2013-09-23 
C语言程序--诡异的结果#include stdio.hint main (int argc, char* argv[ ]){double d 3.4int b 85

C语言程序--诡异的结果

#include <stdio.h>
int main (int argc, char* argv[ ])
{
double d = 3.4;
int b = 858993459;
printf("%d\n", d);
printf("%lf\n", b);

return 0;
}

各位同仁,最近遇到一个让我匪夷所思的问题,希望大家能帮忙解决!大家对这个问题的结果,可以尽情的发表个人看法,本人尽所能提供分数。先谢谢了~~~
C?诡异的结果 c语言 c
[解决办法]
格式符号与变量不匹配,undefined behaviour
[解决办法]

干编程这么多年,编译器bug 我只遇到过一次。
[解决办法]
http://bbs.csdn.net/topics/100022764
[解决办法]
在论坛混的这么久了,
printf函数式格式化输出应该是老问题了吧!

格式不对应的话,输出的结果是无法预知的!没什么好说!
格式对了,出现诡异的现象可以讨论下!
[解决办法]
引用:
#include <stdio.h>
int main (int argc, char* argv[ ])
{
double d = 3.4;
int b = 858993459;
printf("%d\n", d);
printf("%lf\n", b);

return 0;
}

各位同仁,最近遇到一个让我匪夷所思的问题,希望大家能帮忙解决!大家对这个问题的结果,可以尽情的发表个人看法,本人尽所能提供分数。先谢谢了~~~



是这样的,double d = 3.4; int b = 858993459; 在这里,你的d 和 b其实在计算机中都是以二进制方式存储的,无论是浮点数还是整数都是二进制的存在内存当中,对吧?计算机无法知道你在该块内存中存的到底是浮点数还是整数,但c是怎么知道的呢?在这里,C程序是用你所使用的格式化说明符来访问该变量,就是说怎么解释存在这个地址中的二进制的含义,你用%lf就会以浮点方式访问这些二进制,你用%d就是用整型方式访问这些存在内存中的二进制,其实在这里3.4 和 858993459 在内存中的二进制是一样的,由于是一样的数值在内存中,你用什么格式说明符访问,就怎么解释他们,所以会有这样的结果啦。

[解决办法]
引用:
Quote: 引用:

#include <stdio.h>
int main (int argc, char* argv[ ])
{
double d = 3.4;
int b = 858993459;
printf("%d\n", d);
printf("%lf\n", b);

return 0;


}


各位同仁,最近遇到一个让我匪夷所思的问题,希望大家能帮忙解决!大家对这个问题的结果,可以尽情的发表个人看法,本人尽所能提供分数。先谢谢了~~~



是这样的,double d = 3.4; int b = 858993459; 在这里,你的d 和 b其实在计算机中都是以二进制方式存储的,无论是浮点数还是整数都是二进制的存在内存当中,对吧?计算机无法知道你在该块内存中存的到底是浮点数还是整数,但c是怎么知道的呢?在这里,C程序是用你所使用的格式化说明符来访问该变量,就是说怎么解释存在这个地址中的二进制的含义,你用%lf就会以浮点方式访问这些二进制,你用%d就是用整型方式访问这些存在内存中的二进制,其实在这里3.4 和 858993459 在内存中的二进制是一样的,由于是一样的数值在内存中,你用什么格式说明符访问,就怎么解释他们,所以会有这样的结果啦。



要检验他们在内存中的二进制是否相等也很容易啦,试试这段代码,完全可以用我刚刚说的解释,怎么样是不是清楚为什么了?
#include <stdio.h>

int main(void)
{
        double  a = 3.4;
        printf("%d\n", a);
        printf("%lf\n", a);
        return 0;
}

在我的机子上输出结果是
858993459
3.400000
毫无疑问,我刚刚说的得到了验证了。。。
[解决办法]
试试这个看结果
int main (){
        double  a = 3.4;
        printf("%lld,%llx\n", a,a);
        printf("%lf\n", a);
        long long *la =(long long)&a;
        unsigned int * ia=(int *)&a;
        printf("%lld,%llx\n", *la,*la);
        printf("%d,%d\n", *ia,*ia);

        return 0;
}
结果如下:

as long long = 4614838538166547251,400b333333333333
as double = 3.400000
ptr cast to long long ,value=4614838538166547251,400b333333333333
ptr cast to unsigned int ,val =858993459,1074475827
至于 贴主的代码
#include <stdio.h>
int main (int argc, char* argv[ ])
{
double d = 3.4;
int b = 858993459;
printf("%d\n", d);//%d-->int int 比double内存占用小,
                              // char, short, int---》int;
                          // int 32Bits 参数传递时是4字节,double 8字节
                          // 够用,截取一部分使用而已 


printf("%lf\n", b);//%lf,%f --->double ,b---》 int 4字节 不够用,则拼凑
                       
        //  堆栈当前内容:
        // [       b                        ]实参 b         
        // [EFLAGS                          ] 状态寄存器,
        // [ret address = next code address ]返回地址
        // [                                ]printf的自动变量 
         return 0;
}

状态寄存器,和返回地址的的顺序,大概如此,不记得了;
如果这个顺序是对的,b,和调用函数前的状态寄存器的值凑成一个double ,输出;
否则b,和函数返回地址的值,凑成一个double ,输出。

所以,这种输出绝对是非常诡异的!!


[解决办法]

引用:
Quote: 引用:

Quote: 引用:

#include <stdio.h>
int main (int argc, char* argv[ ])
{
double d = 3.4;
int b = 858993459;
printf("%d\n", d);
printf("%lf\n", b);

return 0;
}

各位同仁,最近遇到一个让我匪夷所思的问题,希望大家能帮忙解决!大家对这个问题的结果,可以尽情的发表个人看法,本人尽所能提供分数。先谢谢了~~~



是这样的,double d = 3.4; int b = 858993459; 在这里,你的d 和 b其实在计算机中都是以二进制方式存储的,无论是浮点数还是整数都是二进制的存在内存当中,对吧?计算机无法知道你在该块内存中存的到底是浮点数还是整数,但c是怎么知道的呢?在这里,C程序是用你所使用的格式化说明符来访问该变量,就是说怎么解释存在这个地址中的二进制的含义,你用%lf就会以浮点方式访问这些二进制,你用%d就是用整型方式访问这些存在内存中的二进制,其实在这里3.4 和 858993459 在内存中的二进制是一样的,由于是一样的数值在内存中,你用什么格式说明符访问,就怎么解释他们,所以会有这样的结果啦。



要检验他们在内存中的二进制是否相等也很容易啦,试试这段代码,完全可以用我刚刚说的解释,怎么样是不是清楚为什么了?
#include <stdio.h>

int main(void)
{
        double  a = 3.4;
        printf("%d\n", a);
        printf("%lf\n", a);
        return 0;


}

在我的机子上输出结果是
858993459
3.400000
毫无疑问,我刚刚说的得到了验证了。。。



在这个例子,碰巧而已。

在C语言里
1.从int or float转换到double类型,精确值能保留下来
2.从double or float转换成int类型,将会向零截断。C标准并没有对这种情况规定固定结果。

另外,如果采用80位扩展精度格式,由于截断或溢出,数据从寄存器回到内存,再取回寄存器,其值会产生一些变化,这对程序员来说是不可见的,所以会产生一些奇独的结果
[解决办法]
个人觉得。。这个问题,其实没有必要讨论太多。
有什么用呢?又有哪个标准允许这样用呢?

热点排行