为什么printf是c正在产生这个输出

时间:2014-12-04 20:01:01

标签: c

这是我在C中的以下代码

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

输出

4 0.000000 

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

5 个答案:

答案 0 :(得分:6)

4是整数而不是浮点数。你应该使用:

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

其中第二个数字是double(或float)值。

答案 1 :(得分:5)

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

  

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

%f格式说明符指定用于floatdouble值(事实上,printf()是可变参数函数,因此默认参数提升适用于它)4int类型的整数常量。

有效示例调用​​:

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

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

答案 2 :(得分:2)

问题是你骗了printf。由于您已使用%f格式说明符,因此您承诺传递浮点值。但是,你的第二个参数是整数类型。这会调用未定义的行为,这可能会导致您看到的内容。

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

一个好的编译器可以帮助您检测此类错误。请尝试打开警告。 (对于GCC,-Wall会告诉你这个问题。)

为什么会这样?通常,如果我们调用一个期望double 4为其参数的函数,编译器将隐式地将int转换为double。但是,对于printf之类的变量函数是1,语言表示不会发生这样的转换。实际上,不能发生,因为printf接受多种类型的参数,所以它们应该转换为什么类型? (唯一发生的事情是升级。例如,4.0f会提升为double。)程序员有责任事先在此进行类型转换案件。 (GCC可以警告错误类型的原因是它解析格式字符串并且 - 因为printf是一个标准函数 - 理解它的含义。语言不需要这个。)

答案 3 :(得分:2)

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

符合C标准(7.21.6.1 fprintf函数 - 同样适用于printf)

  

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

  

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

您使用的格式说明符%f的参数类型为int,而不是double

答案 4 :(得分:0)

通常,当您将一个整数作为参数传递给函数时,如果该参数应该是一个浮点数(根据函数的原型),编译器会自动将其转换为浮点数 - 点数量。

但是,printf(以及采用可变数量参数的所有其他函数)不指定原型中...所涵盖的参数的预期类型。因此,编译器不会进行任何自动转换。 (它会执行其他操作,称为默认参数提升。)

因此,当您调用printf("%f", 4)时,编译器会将4作为int传递,但printf会查找double。这种不匹配会触发未定义的行为 - 任何事情都可能发生。

现在,当参数类型与格式字符串不匹配时,许多编译器可以解析printf格式字符串并警告,因此他们可以根据需要插入转换代码(未定义的行为包括"它完全按照预期在此系统上运行")但它们通常不会,因为您应该修复代码,使其按预期工作所有编译器,而不仅仅是那些有用的编译器。

撰写printf("%f", 4.0)printf("%f", (double)int_variable)足以纠正您的代码。