Answers:
"%f"
是double的(或至少一种)正确格式。有是一个没有格式的float
,因为如果你试图传递一个float
到printf
,它会被提升到double
前printf
接受它1。"%lf"
在当前标准下也是可以接受的- l
如果f
指定了转换说明符(除其他外),则指定为无效。
请注意,这是printf
格式字符串与scanf
(和fscanf
等)格式字符串本质上不同的地方。对于输出,你传递一个值,这将被提升float
到double
时,作为可变参数参数传递。对于输入,您要传递一个不会提升的指针,因此您必须告诉scanf
您是否要读取a float
或a double
,因此对于scanf
,%f
表示您想读取a,float
并且%lf
您想读取a double
(并且,其含义是值得,为long double
你使用%Lf
的两种printf
或scanf
)。
1. C99,第6.5.2.2/6节:“如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,而将类型为float的参数提升为双精度。这些称为默认参数提升。” 在C ++中,措词有些不同(例如,它不使用单词“ prototype”),但效果是相同的:所有可变参数在接受函数之前都经过默认提升。
g++
%lf
-Wall -Werror -pedantic
error: ISO C++ does not support the ‘%lf’ gnu_printf format
l
是扩展。C99 / 11和C ++ 11标准要求实现允许它。
scanf
确实要用double
表示%lf
:它抱怨期望float *
并找到double *
了just %f
。
scanf
需要在何处存储它进行读取,因此需要知道有多大的空间被指向-AT是,而printf
所采用的值本身,而“默认参数提升”是指两端向上为double
S,因此l
是本质上是可选的。
给定C99标准(即N1256草案),规则取决于函数类型:fprintf(printf,sprintf,...)或scanf。
以下是摘录的相关部分:
前言
本第二版取消并替代了第一版ISO / IEC 9899:1990,该版本已被ISO / IEC 9899 / COR1:1994,ISO / IEC 9899 / AMD1:1995和ISO / IEC 9899 / COR2:1996修订和更正。与上一版相比的主要变化包括:
%lf
允许使用转换说明符printf
7.19.6.1
fprintf
功能7长度修饰符及其含义是:
l(ell)指定(...)对以下a,A,e,E,f,F,g或G转换说明符无效。
L指定后面的a,A,e,E,f,F,g或G转换说明符适用于long double参数。
对于指定的规则同样fprintf
适用于printf
,sprintf
和类似的功能。
7.19.6.2
fscanf
功能11长度修饰符及其含义是:
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
->长双。可以是%f
,%g
或者%e
取决于您希望数字如何格式化。有关更多详细信息,请参见此处。该l
修正是必需的scanf
有double
,但不是在printf
。
l
小写)修饰符用于整数类型(cplusplus.com/reference/clibrary/cstdio/printf),并且L
用于浮点类型。另外,L
修饰符期望a long double
,而不是plain double
。
l
不需要。printf
double
格式完全符合您使用的%lf
正确printf
格式double
。您的代码没有错。
C语言的旧版本(C99之前的版本)不支持format %lf
in printf
,这会在double
in printf
和的格式说明符之间造成表面上的“不一致” scanf
。这种表面上的不一致已在C99中修复。
您不需要使用%lf
与double
在printf
。%f
如果您愿意,也可以使用(%lf
和%f
等效printf
)。但是,在现代的C,这是绝对意义上喜欢使用%f
与float
,%lf
与double
和%Lf
带long double
,持续两printf
和scanf
。
scanf()
,"%f"
,"%lf"
匹配float *, double *
,而不是float, double
由最后一行暗示。
"%lf"
则未定义;在C99和C11库中,它定义为与相同"%f"
。