这是用C我下面的代码
为什么printf的是c为生产这种输出
printf("%d %f\n",4,4);
输出
4 0.000000
为什么printf的产生这个输出,而不是4.000000排在第二位?
这是用C我下面的代码
为什么printf的是c为生产这种输出
printf("%d %f\n",4,4);
输出
4 0.000000
为什么printf的产生这个输出,而不是4.000000排在第二位?
4是一个整数,而不是一个浮点数。您应该使用:
printf("%d %f\n",4,4.);
其中第二个数字是双精度(或浮点数)值。
使用'4.0'代替'4.'会使最后一个参数的浮点数更加明显。那'''很容易错过。 – Caleb 2014-12-04 20:07:25
这undefined behavior在C. N1570(C11草案)7.21.6.1/9
fprintf函数:
如果转换规范是无效的,该行为是 未定义。 282)如果任何参数不是 对应的转换规范的正确类型,则行为是未定义的。
的%f
格式说明被指定用于float
或double
值(由于事实,即printf()
是可变参数函数,从而适用于它默认参数提升)和4
是int
类型的整数常数。
有效例如呼叫:
printf("%d %f\n", 4, 4.0);
或
printf("%d %f\n", 4, 4.0f);
的问题是,你欺哄printf
。正如您使用%f
格式说明符一样,您已经承诺要传递浮点值。但是,你的第二个参数是整型。这会调用未定义的行为,这可能会导致您看到的内容。
要解决此问题,请使用%d
作为格式说明符或将第二个参数更改为4.0
。
一个好的编译器可以帮助你检测这样的错误。请尝试开启警告。 (对于海湾合作委员会,-Wall
会告诉你这个问题。)
这是为什么?通常,如果我们调用一个函数double
和4
作为它的参数,编译器会隐式地将该int
转换为double
。但是,对于像printf
这样的变速功能而言,该语言表示这种转换不会发生。其实不能发生,因为printf
接受多种类型的参数,所以他们应该转换成什么类型? (唯一发生的是促销。例如,4.0f
将促销到double
。)在这种情况下,程序员有责任事先进行类型转换。 (GCC可以警告错误类型的原因是它解析格式字符串,并且 - 因为printf
是标准函数 - 理解它的含义。语言不需要这样做。)
因为该函数的调用具有未定义的行为。
Accordint到C标准(7.21.6.1 fprintf函数 - 同样是有效的的printf)
9如果转换规范是无效的,该行为是 undefined.275)如果任何参数不是 相应转换规范的正确类型,则行为是未定义的。
而且
女,表示浮点数 FA double参数 转换为十进制表示法中的式[ - ] ddd.ddd,其中 的位数后小数点字符等于 精度规格。
您在使用格式说明%f
与int
,而不是double
类型的参数。
通常,当传递的整数作为参数传递给一个功能,如果这样的说法被认为是一个浮点数(根据函数的原型),编译器自动将其转换为浮点量为您。
但是,printf
(以及其他采用可变数量参数的其他函数)没有在原型中指定...
所涵盖参数的预期类型。因此,编译器不会做任何自动转换。 (它确实别的东西,叫做默认参数推广,来代替。)
所以,当你调用printf("%f", 4)
,编译器经过4为int
,但printf
寻找一个double
。这种不匹配会触发未定义的行为 - 任何事情都可能发生。
如今,许多编译器可以解析printf
格式字符串和警告你当参数类型不与格式字符串匹配,所以他们能插入转换代码为合适的(未定义的行为包括“吧按照预期在本系统上工作“),但他们通常不这样做,因为您应该修复代码,以便其按照预期的方式在全部编译器上运行,而不仅仅是那些非常有用的编译器。
写入printf("%f", 4.0)
或printf("%f", (double)int_variable)
已足以更正您的代码。
它不应该。这里必须有一些其他相关的代码,你没有显示。 – Daniel 2014-12-04 20:02:10
我在只有printf语句的visual studio中试过它。 – 2014-12-04 20:04:33