这是我在C中的以下代码
printf("%d %f\n",4,4);
输出
4 0.000000
为什么printf会产生这个输出而不是第二位的4.000000?
答案 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
格式说明符指定用于float
或double
值(事实上,printf()
是可变参数函数,因此默认参数提升适用于它)4
是int
类型的整数常量。
有效示例调用:
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)
足以纠正您的代码。