简短的回答是它对printf 没有影响,并表示在scanf 中使用float 或double。
对于printf,float 类型的参数被提升为double,因此%f 和%lf 都用于double。对于scanf,您应该使用%f 为float 和%lf 为double。
以下是我们中间语言律师的更多详细信息:
%f 和 %lf 在 printf 系列中没有区别。 ISO C 标准(内所有引用均来自 C11),7.21.6.1 The fprintf function 部分,/7 段声明,用于l 修饰符(我的重点):
指定以下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 段,其中列出了%f 说明符:
表示浮点数的double 参数被转换为十进制表示法
这与函数原型中椭圆后面的参数受默认参数提升的影响有关,如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:
指定以下d、i、o、u、x、X 或n 转换说明符适用于类型指针指向long int 或@ 的参数987654390@; 以下a、A、e、E、f、F、g 或G 转换说明符适用于类型指针指向@987654399 的参数@; 或后面的 c、s 或 [ 转换说明符适用于类型指针指向 wchar_t 的参数。
这会修改该部分的/12 段落,该段落声明为%f:
匹配可选带符号的浮点数、无穷大或NaN,其格式与strtod 函数的主题序列的预期格式相同。对应的参数应该是一个指向浮动的指针。