double
中 printf
的正确格式说明符是什么?是%f
还是%lf
?我相信是%f
,但我不确定。
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
"%f"
是双精度数的(或至少一种)正确格式。 float
没有格式,因为如果您尝试将 float
传递给 printf
,则在 double
收到它1之前,它将被提升为
printf
。 "%lf"
在当前标准下也是可接受的——如果后面跟有 l
转换说明符(等等),f
被指定为无效。请注意,这是
printf
格式字符串与
scanf
(和 fscanf
等)格式字符串显着不同的地方。对于输出,您传递一个 value,当作为可变参数传递时,它将从
float
提升为 double
。对于输入,您要传递一个 指针,该指针不会被提升,因此您必须告诉
scanf
您是否想要读取 float
还是 double
,因此对于 scanf
,%f
表示您想要读取 float
和 %lf
表示您想要读取 double
(并且,对于 long double
,您可以使用 %Lf
来表示 printf
或 scanf
)。
标准(即N1256草案),规则取决于 函数类型:fprintf (printf, sprintf, ...) 或 scanf。 以下是摘录的相关部分:
前言第二版取消并取代第一版 ISO/IEC 9899:1990,经 ISO/IEC 9899/COR1:1994、ISO/IEC 9899/AMD1:1995 和 ISO/IEC 9899/COR2:1996 修订和更正。 与上一版本相比的主要变化包括:
7.19.6.1
%lf
printf
中允许使用转换说明符7
fprintf
函数长度修饰符及其含义是:
l(ell) 指定 (...) 对后面的 a、A、e、E、f、F、g 或 G 转换说明符没有影响。
L指定以下 a、A、e、E、f、F、g 或 G 转换说明符适用于长双精度参数。
为
fprintf
指定的相同规则适用于
printf
、sprintf
和类似函数。7.19.6.211
fscanf
函数长度修饰符及其含义是:
l(ell) 指定 (...) 后面的 a、A、e、E、f、F、g 或 G 转换说明符适用于类型指针为 double 的参数;
L指定以下 a、A、e、E、f、F、g 或 G 转换 说明符适用于类型指针指向 long double 的参数。
12转换说明符及其含义是: a,e,f,g 匹配可选带符号的浮点数,(...)
14转换说明符 A、E、F、G 和 X 也是有效的,并且其行为分别与 a、e、f、g 和 x 相同。
长话短说,对于
fprintf
,指定了以下说明符和相应的类型:
%f
%Lf
fscanf
来说是:
%f
%lf
%Lf
%lf
是
printf
的完全正确的 double
格式,与您使用的完全一样。你的代码没有任何问题。旧版(C99 之前)C 语言不支持
%lf
中的printf
格式,这在
double
中的
printf
和
scanf
中的格式说明符之间造成了表面上的“不一致”。这种表面上的不一致已在 C99 中得到修复。
您无需将
%lf
与 double
中的
printf
一起使用。如果您愿意,也可以使用
%f
(
%lf
和
%f
在
printf
中是等效的)。但在现代 C 中,更喜欢使用
%f
与
float
、
%lf
与
double
以及
%Lf
与
long double
一起使用,在
printf
和
scanf
中保持一致。