C中%f和%lf有什么区别?
我在C书的C示例中看到了这两个参数,但作者没有详细说明两者之间的区别。 我知道%f
指定浮点数应该取而代之。 我试着查看这个,但很难找到这个w符号。 %lf
怎么样?
printf
系列没有区别。 ISO C11标准(以下所有引用均来自C11),第7.21.6.1 The fprintf function
节l
修饰符(我的粗体) 7.21.6.1 The fprintf function
,段落/7
状态:
指定以下d,i,o,u,x或X转换说明符适用于long int或unsigned long int参数; 后面的n转换说明符适用于指向long int参数的指针; 以下c转换说明符适用于wint_t参数; 以下s转换说明符适用于指向wchar_t参数的指针; 或对后续的a,A,e,E,f,F,g或G转换说明符没有影响。
它不需要修改f
说明符的原因是因为该说明符已经表示一个double
,来自同一节的段落/8
:
表示浮点数的双参数在样式中转换为十进制表示法…
这与函数原型中椭圆后面的参数根据6.5.2.2 Function calls
节6.5.2.2 Function calls
段落/7
进行默认参数提升这一事实有关:
…函数原型声明符中的省略号表示法导致参数类型转换在最后声明的参数之后停止。 默认参数提升是在尾随参数上执行的。
因为printf
(确实是整个类似printf
的函数族)被声明为int printf(const char * restrict format, ...);
使用省略号表示法,该规则适用于此处。 6.5.2.2 Function calls
,第/6
段中介绍了默认参数提升:
如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有float类型的参数提升为double。 这些被称为默认参数促销。
对于scanf
系列,它要求使用double
而不是float
。 第7.21.6.2 The fscanf function /11
节7.21.6.2 The fscanf function /11
:
指定以下d,i,o,u,x,X或n转换说明符适用于具有long int或unsigned long int类型指针的参数; 以下a,A,e,E,f,F,g或G转换说明符适用于类型指针为double的参数; 或者后面的c,s或[转换说明符适用于带有指向wchar_t的类型指针的参数。
这会修改该部分的/12
段,表示%f
:
匹配可选带符号的浮点数,无穷大或NaN,其格式与strtod函数的主题序列的预期格式相同。 相应的参数应该是浮动的指针。
对于scanf
, %f
读入float
, %lf
读入double
。
对于printf
:在C99及更高版本中,它们都是相同的,它们可以打印float
或double
float
。 在C89中, %lf
导致了未定义的行为,尽管它是将其视为%f
的常见扩展。
一个说明符可以用于printf
两种不同类型的原因是因为默认参数提升 ; 当用于调用函数而不匹配函数原型中的参数时, float
类型的参数被提升为double
。 所以printf
在任何一种情况下都看到了double
。
printf()正常忽略%lf中的宽度修饰符。 或者,为了更准确,%f需要双倍 – varargs将始终将浮动参数提升一倍。