printf中double
的正确格式说明符是什么?它是%f
还是%lf
?我相信它是%f
,但我不确定。
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
答案 0 :(得分:536)
"%f"
是double的(或至少一种)正确格式。 没有float
的格式,因为如果您尝试将float
传递给printf
,它会被提升为double
之前printf
收到 1 。根据当前标准,"%lf"
也可以接受 - l
被指定为如果后跟f
转化说明符(等等)则无效。
请注意,这是printf
格式字符串与scanf
(和fscanf
等)格式字符串大不相同的地方。对于输出,您传递值,当作为可变参数传递时,该值将从float
提升为double
。对于输入,您传递的是指针,但未提升,因此您必须告诉scanf
您是否要阅读float
或double
,因此对于scanf
,%f
表示您想要阅读float
而%lf
表示您想要阅读double
(并且,为了它的价值,一个long double
,%Lf
或printf
使用scanf
。
<子> 1. C99,§6.5.2.2/ 6:“如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有float类型的参数提升为double。这些被称为默认参数促销。“在C ++中,措辞有些不同(例如,它不使用“原型”一词)但效果是相同的:所有可变参数在被函数接收之前经历默认促销。 子>
答案 1 :(得分:55)
鉴于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。 上一版的主要变化包括:
{li}
%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转换说明符适用于带有类型指针的参数双
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
- &gt;双%Lf
- &gt;长双。和fscanf
是:
%f
- &gt;浮%lf
- &gt;双%Lf
- &gt;长双。答案 2 :(得分:18)
可以是%f
,%g
或%e
,具体取决于您希望如何格式化数字。有关详细信息,请参阅here。 l
scanf
需要double
修饰符,而printf
则不需要。{/ p>
答案 3 :(得分:9)
printf
的正确double
格式为%lf
,与您使用的格式完全相同。您的代码没有任何问题。
语言中的旧版(C99之前版本)不支持%lf
中的格式printf
,这会产生肤浅的&#34;不一致&#34;在double
和printf
中scanf
的格式说明符之间。表面上的不一致已在C99中修复。
因此,在现代C中,将%f
与float
,%lf
与double
和%Lf
与long double
一起使用是绝对有意义的。始终同时包含printf
和scanf
。
答案 4 :(得分:7)
%Lf
(注意首都L
)是format specifier的long doubles。
对于普通doubles
,%e
,%E
,%f
,%g
或%G
都可以。
答案 5 :(得分:-2)
对于双倍,您只需使用%lf
,或者您可以根据自己的喜好使用以下任何一种
%e
或%E
%g
或%G
表示正常或指数表示法,以其大小为准。