printf中double的正确格式说明符是什么?是%f还是%f ?我相信是%f,但我不确定。

代码示例

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}

它可以是%f, %g或%e,这取决于您希望如何格式化数字。请看这里了解更多细节。在带double的scanf中需要l修饰符,但在printf中不需要。


Lf(注意大写的L)是长双精度的格式说明符。

对于普通的double类型,%e, %e, %f, %g或%g都可以。


“%f”是(或至少一个)double的正确格式。浮点数没有格式,因为如果你试图将一个浮点数传递给printf,它会在printf接收到它1之前升格为double。在当前标准下,“%lf”也是可以接受的——如果后面跟着f转换说明符(以及其他),则l被指定为无效。

Note that this is one place that printf format strings differ substantially from scanf (and fscanf, etc.) format strings. For output, you're passing a value, which will be promoted from float to double when passed as a variadic parameter. For input you're passing a pointer, which is not promoted, so you have to tell scanf whether you want to read a float or a double, so for scanf, %f means you want to read a float and %lf means you want to read a double (and, for what it's worth, for a long double, you use %Lf for either printf or scanf).


1. C99,§6.5.2.2/6:“如果表示被调用函数的表达式的类型不包括原型,则对每个实参执行整数提升,类型为float的实参将提升为double。这些被称为默认参数提升。”在c++中,措辞有些不同(例如,它不使用“prototype”这个词),但效果是一样的:所有可变参数在被函数接收之前都会进行默认的提升。


对于C99标准(即N1256草案),规则取决于 函数类型:fprintf (printf, sprintf,…)或scanf。

以下是相关部分摘录:

Foreword This second edition cancels and replaces the first edition, ISO/IEC 9899:1990, as amended and corrected by ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995, and ISO/IEC 9899/COR2:1996. Major changes from the previous edition include: %lf conversion specifier allowed in printf 7.19.6.1 The fprintf function 7 The length modifiers and their meanings are: l (ell) Specifies that (...) has no effect on a following a, A, e, E, f, F, g, or G conversion specifier. L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to a long double argument.

为fprintf指定的相同规则也适用于printf、sprintf和类似的函数。

7.19.6.2 The fscanf function 11 The length modifiers and their meanings are: l (ell) Specifies that (...) that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to double; L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to long double. 12 The conversion specifiers and their meanings are: a,e,f,g Matches an optionally signed floating-point number, (...) 14 The conversion specifiers A, E, F, G, and X are also valid and behave the same as, respectively, a, e, f, g, and x.

长话短说,对于fprintf,指定了以下说明符和相应的类型:

%f -> double %Lf ->长双。

对于fscanf,它是:

%f ->浮点数 %lf -> double %Lf ->长双。


Format %lf是double的一个完全正确的printf格式,与您使用的完全相同。你的代码没有问题。

旧版本(c99之前)的C语言不支持printf中的Format %lf,这在printf中的double格式说明符和scanf中造成了表面上的“不一致”。这种表面上的不一致在C99中得到了修复。

你不需要在printf中使用%lf和double。如果您愿意,也可以使用%f (%lf和%f在printf中是等价的)。但在现代C语言中,更喜欢使用%f与float, %lf与double, %lf与long double,在printf和scanf中始终一致是完全有意义的。