假设我在 C 中有以下代码:
double var;
scanf("%lf", &var);
printf("%lf", var);
printf("%f", var);
它从标准输入变量“var”中读取,然后在标准输出“var”中打印两次。我知道这就是您从标准输入读取双变量的方式,但我的问题是:
- 为什么可以用 %lf 打印双精度?
- 为什么可以使用 %f 打印双精度?
- 哪一个更好更正确使用?
printf对于像and之类的可变参数函数scanf,参数被提升,例如,任何较小的整数类型被提升为int,float被提升为double。
scanf带指针参数,所以提升规则无效。它必须使用%fforfloat*和%lffor double*。
printf永远不会看到float争论,float总是被提升为double。格式说明符是%f. 但 C99 也说与中%lf相同:%fprintf
C99 §7.19.6.1
fprintf函数
l(ell) 指定后面的d,i,o,u,x, orX转换说明符适用于long intorunsigned long int参数;后面的n转换说明符适用于指向long int参数的指针;以下c转换说明符适用于wint_t参数;后面的s转换说明符适用于指向wchar_t参数的指针;或对后面a的 ,A,e,E,f,F,g, 或G转换说明符没有影响。
当 afloat传递给 时printf,它会自动转换为 a double。这是默认参数提升的一部分,它适用于具有可变参数列表(包含...)的函数,主要是出于历史原因。因此,a 的“自然”说明符float必须%f与double参数一起使用。所以%fand%lf说明符printf是一样的;他们都double取值。
调用时scanf,传递的是指针,而不是直接值。指向的指针float不会转换为指向的指针double(这不起作用,因为当您更改指针类型时,指向的对象无法更改)。因此,对于scanf,参数 for%f必须是指向 的指针float,而参数 for%lf必须是指向 的指针double。
就我阅读手册页而言,scanf 表示“l”长度修饰符表示(在浮点的情况下)参数是 double 类型而不是 float 类型,因此您可以使用“lf, le, lg”。
至于打印,官方说 'l' 仅适用于整数类型。因此,某些系统或某些标准可能不支持它。例如,我在编译时收到以下错误消息gcc -Wall -Wextra -pedantic
a.c:6:1: warning: ISO C90 does not support the ‘%lf’ gnu_printf format [-Wformat=]
因此,您可能需要仔细检查您的标准是否支持该语法。
总而言之,我会说您使用 '%lf' 阅读并使用 '%f' 打印。