printf中double的正确格式说明符是什么?是%f还是%lf?我相信是%f,但我不确定。
代码示例
#include <stdio.h>

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


评论

如果您使用的是C89库,则“%lf”是未定义的;在C99和C11库中,它定义为与“%f”相同。

您的变体与以往一样正确。 %lf是double的正确格式说明符。但是在C99中变得如此。在此之前,必须使用%f。

#1 楼

"%f"是双精度格式的(或至少一种)正确格式。 float没有格式,因为如果您尝试将float传递给printf,则它将在double收到之前被提升为printf1。 "%lf"在当前标准下也是可以接受的-如果l转换说明符(除其他外)后面指定为f,则无效。

请注意,这是printf格式字符串大不相同的地方来自scanf(和fscanf等)格式的字符串。对于输出,您正在传递一个值,当作为可变参数传递时,该值将从float提升为double。对于输入,您要传递一个不会提升的指针,因此必须告诉scanf是要读取float还是double,因此对于scanf%f表示您想读取float,而%lf表示您想读取一个double(对于long double来说,它的价值是,您可以将%Lf用作printfscanf)。




1。 C99,第6.5.2.2/6节:“如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,而将类型为float的参数提升为双精度。称为默认参数提升。”在C ++中,措词有些不同(例如,它不使用单词“ prototype”),但效果是相同的:所有可变参数在接受函数之前都经过默认提升。


评论


请注意,使用-Wall -Werror -pedantic进行编译时,g ++拒绝%lf:错误:ISO C ++不支持'%lf'gnu_printf格式

– kynan
2013年6月10日12:16

@kynan:如果是这样(至少假设当前版本为g ++),那是g ++中的错误。对于C89 / 90和C ++ 98/03,允许l是扩展。 C99 / 11和C ++ 11标准要求实现允许它。

–杰里·科芬(Jerry Coffin)
2013年6月10日13:16

奇怪的是,scanf确实希望用%lf表示双精度型:它抱怨它期望float *并只用%f找到了double *。

–埃里克·丹
2014年11月14日在7:23

@JerryCoffin g ++仍默认为g ++ 98模式

– M.M
2015年7月19日,0:33

@EricDand这是因为scanf会使用指向存储所读取内容的指针,因此需要知道所指向的空间有多大,而printf会自己获取值,而“默认参数提升”则意味着两者最终都加倍,因此l本质上是可选的。

– TripeHound
15年8月26日在13:58

#2 楼

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

这里提取了相关部分:


前言

本第二版取消并代替经ISO / IEC 9899 / COR1修订和更正的第一版ISO / IEC 9899:1990 :1994,ISO / IEC 9899 / AMD1:1995和ISO / IEC 9899 / COR2:1996。
与上一版相比,主要变化包括:



%lf中允许的printf转换说明符


7.9.6.1 fprintf函数

7长度修饰符及其含义为:

l (ell)指定(...)对后面的a,A,e,E,f,F,g或G转换说明符无效。

L指定后面的a, A,e,E,f,F,g或G转换说明符适用于长双精度参数。


fprintf指定的相同规则也适用于printfsprintf和类似功能。


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-> double

%Lf-> long double。


#3 楼

可以是%f%g%e,具体取决于您希望数字如何格式化。有关更多详细信息,请参见此处。在lscanf中需要double修饰符,但在printf中不是必需的。

评论


-1:l(小写)修饰符用于整数类型(cplusplus.com/reference/clibrary/cstdio/printf),而L则用于浮点类型。此外,L修饰符期望长双倍,而不是普通双倍。

–user470379
2011年1月19日19:28

user470379:那么我的答案在哪里呢?我不是说过,printf中不需要l来加倍。

–维生素
2011年1月20日上午10:09

#4 楼

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

旧的(C99之前)C语言版本不支持%lfprintf格式,这在doubleprintfscanf格式说明符之间造成了表面的“不一致”。这种表面上的不一致已在C99中修复。

您无需在%lf中将doubleprintf一起使用。如果愿意,也可以使用%f%lf%fprintf中是等效的)。但是在现代C语言中,最好在%ffloat中始终使用%lfdouble%Lflong doubleprintfscanf一致。

评论


使用scanf()时,“%f”,“%lf”匹配浮点数*,双精度*,而不是浮点数,最后一行所暗示的是double。

–chux-恢复莫妮卡
19年12月8日在13:09

#5 楼

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

对于普通doubles%e%E%f%g%G都可以。

评论


%g和%G有什么区别?

– yanpas
16 Jan 10 '13 at 13:29

@yanpas,分别为指数符号的小写/大写。

–FrédéricHamidi
16年1月10日在14:18

抱歉,%g和%G确实输出E符号。他们在不同情况下也会输出INF和inf

– yanpas
16 Jan 10 '14在14:26