void main()
{
float x = 8.2;
int r = 6;
printf ( "%f" , r/4);
}
很明显,我没有明确地将printf函数中的r(int类型)强制转换为float。但是,如果我改变声明x和r的顺序并首先声明r然后x i得到不同的结果(在这种情况下它是一个垃圾值)。我再次使用x 在程序的任何地方..这些是我想要错的东西......我想保持他们的方式。但是当我执行第一段代码时,我得到了157286.375011(垃圾值)。
void main()
{
int r = 6;
float x = 8.2;
printf ( "%f" , r/4);
}
如果我执行上面的代码,我得到0.000000作为结果。我知道结果可能会出错,因为我在printf中使用%f时应该是%d ...结果可能是错误的...但我的问题是当我改变变量定义序列时结果会发生变化的原因。无论是对还是错,不应该是一样的吗?
为什么会这样?
答案 0 :(得分:8)
printf
没有任何类型检查。它依赖于您自己进行检查,验证所有类型都与格式说明符匹配。
如果你不这样做,你就进入了未定义行为的领域,任何事情都可能发生。 printf
函数正在尝试根据您使用的格式说明符来解释指定的值。如果它们不匹配,就会繁荣。
为%f
指定int
是无稽之谈,但您已经知道......
答案 1 :(得分:3)
f
转换说明符采用double
参数,但您传递的是int
参数。将int
参数传递给f
转换说明符是未定义的行为。
在这个表达式中:
r / 4
两个操作数都是int
类型,结果也是int
类型。
这是你想要的:
printf ("%f", r / 4.0);
答案 2 :(得分:1)
当printf
抓取可选变量(即char *
之后的变量告诉它要打印什么)时,它必须将它们从堆栈中取出。 double
通常为64位(8字节),而int
为32位(4字节)。
此外,与整数相比,浮点数具有奇怪的内部结构。
由于您传递int
代替double
,printf
正试图从堆栈中取出8个字节而不是4个字节,并且它正在尝试解释字节一个int
作为double
的字节。
因此,您不仅得到包含没有人知道的4个字节的内存,而且您还要解释该内存 - 这是int
的4个字节和4个字节的随机从不知道的东西 - 好像它是double
。
所以是的,奇怪的事情将要发生。当你重新编译(甚至是重新运行)一个程序时,你只需要在没有malloc
'并且没有存储的情况下肆无忌惮地选择内存,将会变得无法预测并且变化很大。
不要这样做。