在printf中修正double的格式说明符
 printf中double的正确格式说明符是什么? 是%f还是%lf ? 我相信它的%f但我不确定。 
代码示例
 #include <stdio.h> int main() { double d =1.4; printf("%lf", d); //is this wrong? } 
	
  "%f"是双精度格式(或至less一个)。  float没有格式,因为如果你尝试传递一个float到printf ,它会在printf收到它之前被提升为double 1 。 在当前的标准下, "%lf"也是可以接受的 – 如果后面跟着f转换说明符(除其他外), l被指定为无效。 
 请注意,这是printf格式string与scanf (和fscanf等)格式string大不相同的地方。 对于输出,你传递一个值 ,当作为一个可变parameter passing时,这个值将从float提升到double 。 对于input来说,你传递的是一个没有被提升的指针 ,所以你必须告诉scanf你要读取一个float还是一个double ,所以对于scanf , %f表示你想读一个float , %lf表示你想要读取一个double (以及对于long double的值,对于printf或scanf ,使用%Lf )。 
1. C99,§6.5.2.2/ 6:“如果表示被调用函数的expression式的types不包含原型,则对每个参数执行整数提升,并将具有floattypes的参数提升为double。这些被称为默认参数促销。“ 在C ++中,措辞有些不同(例如,它不使用“原型”这个词),但效果是相同的:所有可变参数在被函数接收之前都进行默认促销。
鉴于C99标准(即N1256草案),规则取决于函数种类:fprintf(printf,sprintf,…)或scanf。
这里是提取的相关部分:
前言
本第二版取消并取代了ISO / IEC 9899 / COR1:1994,ISO / IEC 9899 / AMD1:1995和ISO / IEC 9899 / COR2:1996修订和修正的第一版ISO / IEC 9899:1990。 以前版本的重大变化包括:
%lf允许在printf转换说明符7.19.6.1
fprintf函数7长度修饰符及其含义如下:
l (ell)指定(…)对后续的a,e,e,f,f,g或G转换说明符无效。
L指定以下a,A,e,E,f,F,g或G转换说明符适用于长双参数。
 为fprintf指定的规则同样适用于printf , sprintf和类似的函数。 
7.19.6.2
fscanf函数11长度修饰符及其含义如下:
l (ell)指定(…)后面的a,A,e,E,f,F,g或G转换说明符应用于指针types为double的参数;
L指定以下a,A,e,E,f,F,g或G转换说明符应用于指针types为long double的参数。
12转换说明符及其含义如下:a,e,f,g匹配一个可选的有符号浮点数,(…)
14转换说明符A,E,F,G和X也是有效的,分别表示a,e,f,g和x。
 长话短说,为fprintf指定了以下说明符和相应的types: 
-   %f– >双
-   %Lf– >长双。
 对于fscanf来说是这样的: 
-   %f– >浮动
-   %lf– > double
-   %Lf– >长双。
 它可以是%f , %g或%e这取决于您希望如何格式化数字。  在这里看到更多的细节。 在scanf , l修饰符是必需的,但在printf不能。 
  %Lf (注意大写L )是长打的格式说明符 。 
 对于普通的doubles , %e , %E , %f , %g或%G都可以。 
 用于double的正确的printf格式是%lf ,与您使用的完全相同。 你的代码没有问题。 
  printf中的%lf格式在旧版(C99之前的版本)中不被支持,这在printf和scanf double格式说明符之间产生了表面“不一致”。 这个肤浅的不一致已经在C99中得到了修复。 
 所以在现代的C语言中,最好使用%f和float , %lf使用double , %Lf使用printf和scanf long double 。 
 对于双重你可以简单地使用%lf或者你可以根据你的喜好使用下面的任何一个 
  %e或%E为指数格式的值 
  %g或%G ,对于正常或指数符号,取其大小更适合。 
在这里阅读更多C中所有格式说明符的列表