2014-12-04 81 views
1

这是用C我下面的代码
为什么printf的是c为生产这种输出

printf("%d %f\n",4,4); 

输出

4 0.000000 

为什么printf的产生这个输出,而不是4.000000排在第二位?

+0

它不应该。这里必须有一些其他相关的代码,你没有显示。 – Daniel 2014-12-04 20:02:10

+1

我在只有printf语句的visual studio中试过它。 – 2014-12-04 20:04:33

回答

6

4是一个整数,而不是一个浮点数。您应该使用:

printf("%d %f\n",4,4.); 

其中第二个数字是双精度(或浮点数)值。

+3

使用'4.0'代替'4.'会使最后一个参数的浮点数更加明显。那'''很容易错过。 – Caleb 2014-12-04 20:07:25

5

undefined behavior在C. N1570(C11草案)7.21.6.1/9fprintf函数

如果转换规范是无效的,该行为是 未定义。 282)如果任何参数不是 对应的转换规范的正确类型,则行为是未定义的。

%f格式说明被指定用于floatdouble值(由于事实,即printf()是可变参数函数,从而适用于它默认参数提升)和4int类型的整数常数。

有效例如呼叫:

printf("%d %f\n", 4, 4.0); 

printf("%d %f\n", 4, 4.0f); 
2

的问题是,你欺哄printf。正如您使用%f格式说明符一样,您已经承诺要传递浮点值。但是,你的第二个参数是整型。这会调用未定义的行为,这可能会导致您看到的内容。

要解决此问题,请使用%d作为格式说明符或将第二个参数更改为4.0

一个好的编译器可以帮助你检测这样的错误。请尝试开启警告。 (对于海湾合作委员会,-Wall会告诉你这个问题。)

这是为什么?通常,如果我们调用一个函数double4作为它的参数,编译器会隐式地将该int转换为double。但是,对于像printf这样的变速功能而言,该语言表示这种转换不会发生。其实不能发生,因为printf接受多种类型的参数,所以他们应该转换成什么类型​​? (唯一发生的是促销。例如,4.0f将促销到double。)在这种情况下,程序员有责任事先进行类型转换。 (GCC可以警告错误类型的原因是它解析格式字符串,并且 - 因为printf是标准函数 - 理解它的含义。语言不需要这样做。)

2

因为该函数的调用具有未定义的行为。

Accordint到C标准(7.21.6.1 fprintf函数 - 同样是有效的的printf)

9如果转换规范是无效的,该行为是 undefined.275)如果任何参数不是 相应转换规范的正确类型,则行为是未定义的。

而且

女,表示浮点数 FA double参数 转换为十进制表示法中的式[ - ] ddd.ddd,其中 的位数后小数点字符等于 精度规格。

您在使用格式说明%fint,而不是double类型的参数。

0

通常,当传递的整数作为参数传递给一个功能,如果这样的说法被认为是一个浮点数(根据函数的原型),编译器自动将其转换为浮点量为您。

但是,printf(以及其他采用可变数量参数的其他函数)没有在原型中指定...所涵盖参数的预期类型。因此,编译器不会做任何自动转换。 (它确实别的东西,叫做默认参数推广,来代替。)

所以,当你调用printf("%f", 4),编译器经过4为int,但printf寻找一个double。这种不匹配会触发未定义的行为 - 任何事情都可能发生。

如今,许多编译器可以解析printf格式字符串和警告你当参数类型不与格式字符串匹配,所以他们插入转换代码为合适的(未定义的行为包括“吧按照预期在本系统上工作“),但他们通常不这样做,因为您应该修复代码,以便其按照预期的方式在全部编译器上运行,而不仅仅是那些非常有用的编译器。

写入printf("%f", 4.0)printf("%f", (double)int_variable)已足以更正您的代码。

相关问题