2010-02-16 56 views
9

我正在研究这个程序,我注意到使用%f作为double和%d作为float使我完全不同。有人知道为什么发生这种情况?使用%d和%f的C printf

int main() 
{ 
float a = 1F; 
double b = 1; 

printf("float =%d\ndouble= %f", a, b); 
} 

这是输出

float = -1610612736 
double = 190359837192766135921612671364749893774625551025007120912096639276776057269784974988808792093423962875123204096.0000 
+0

感谢。我现在明白了。 – user69514 2010-02-16 18:44:45

回答

4

由于变量参数的工作方式,C不知道您实际通过的值的类型,而不是%d%f。当你传递一个可变参数时,你基本上是在做(void*)&myvalue,因为除了格式化字符串中给出的内容外,编译器和运行时的函数都不能确定变量的类型。因此,即使存在可用的隐式转换,编译器也不知道它是否需要。

那么,double在大多数系统上是8个字节,而float是4个字节。所以这两种类型不是二进制兼容的。这就像试图将一个字符串解释为双重或其他不兼容的类型。

+2

正确,但它并不是专门针对'float'和'double'之间的兼容性。实际上,'float'类型的可变参数在传递之前总是被提升为'double',这意味着'float'类型在这里没有涉及任何东西。传递给'printf'的两个值都是'double'类型。第一个内部被解释为一个'int'(因为'%d'说明符)。 'int'和'double'之间的不兼容是导致观察到的未定义行为的原因。 – AnT 2012-10-24 19:16:29

3

它与数据的内部表示做。你试图打印一个float,就好像它是一个int,它具有完全不同的内部(二进制)表示。

案件是类似的。 float变量后面可能有垃圾(任何数据)。垃圾被解释为double值的一部分。

4

%d代表十进制,它期望类型为int(或一些较小的有符号整数类型,然后得到提升)的参数。浮点类型floatdouble都通过相同的方式(提升为double),并且它们都使用%f。在C99中,您还可以使用%lf来表示较大尺寸的double,但这纯粹是表面化妆(请注意,scanf不会发生任何促销,这实际上有所不同)。

+0

嗯,这是真的http://codepad.org/labE8lgy,但我不知道如何实际工作.. – Earlz 2010-02-16 16:34:12

0

%d打印一个整数,所以你的printf将你的变量a解释为一个int。

使用gcc 3.4.6,我在你的代码中获得了两个值的0(在关闭F初始化之后,因为这导致了编译器错误)。我怀疑这与被解释为int的变量的一部分有关,然后编译器会感到困惑......(可能有更好的解释,但我想不起来)。

对于两个变量,对于两个变量都使用%f来表示两个变量1.000000。

你可以找到接近底部的转换字符此页的清单:所有的意见

http://www.exforsys.com/tutorials/c-language/managing-input-and-output-operations-in-c.html

+0

与'F'相关的编译器错误是因为它不能附加到一个整数(例如,'1.0F'很好)。 – RastaJedi 2016-05-07 10:24:10

相关问题