[英]Scanf/Printf double variable C
Let's say I have this following bit of code in C: 假设我在C中有以下代码:
double var;
scanf("%lf", &var);
printf("%lf", var);
printf("%f", var);
It reads from stdin variable 'var' and then prints twice in stdout 'var'. 它从stdin变量'var'读取,然后在stdout'var'中打印两次。 I understand that's how you read a double variable from stdin, but my questions are:
我理解你是如何从stdin读取双变量的,但我的问题是:
For variable argument functions like printf
and scanf
, the arguments are promoted, for example, any smaller integer types are promoted to int
, float
is promoted to double
. 对于像
printf
和scanf
这样的变量参数函数,会提升参数,例如,任何较小的整数类型都会提升为int
, float
会提升为double
。
scanf
takes parameters of pointers, so the promotion rule takes no effect. scanf
接受指针参数,因此促销规则不起作用。 It must use %f
for float*
and %lf
for double*
. 它必须使用
%f
表示float*
, %lf
表示double*
。
printf
will never see a float
argument, float
is always promoted to double
. printf
永远不会看到float
参数, float
总是被提升为double
。 The format specifier is %f
. 格式说明符是
%f
。 But C99 also says %lf
is the same as %f
in printf
: 但是C99还说
%lf
与printf
%f
相同:
C99 §7.19.6.1 The
fprintf
functionC99§7.19.6.1的
fprintf
功能
l
(ell) Specifies that a followingd
,i
,o
,u
,x
, orX
conversion specifier applies to along int
orunsigned long int
argument;l
(ell)指定以下d
,i
,o
,u
,x
或X
转换说明符适用于long int
或unsigned long int
参数; that a followingn
conversion specifier applies to a pointer to along int
argument;以下
n
转换说明符适用于指向long int
参数的指针; that a followingc
conversion specifier applies to awint_t
argument;以下
c
转换说明符适用于wint_t
参数; that a followings
conversion specifier applies to a pointer to awchar_t
argument;以下
s
转换说明符适用于指向wchar_t
参数的指针; or has no effect on a followinga
,A
,e
,E
,f
,F
,g
, orG
conversion specifier.或对后续的
a
,A
,e
,E
,f
,F
,g
或G
转换说明符没有影响。
When a float
is passed to printf
, it is automatically converted to a double
. 当
float
传递给printf
,它会自动转换为double
。 This is part of the default argument promotions , which apply to functions that have a variable parameter list (containing ...
), largely for historical reasons. 这是默认参数提升的一部分,它适用于具有可变参数列表(包含
...
)的函数,主要是出于历史原因。 Therefore, the “natural” specifier for a float
, %f
, must work with a double
argument. 因此,
float
的“自然”说明符%f
必须使用double
参数。 So the %f
and %lf
specifiers for printf
are the same; 所以
printf
的%f
和%lf
说明符是相同的; they both take a double
value. 他们都采取
double
价值。
When scanf
is called, pointers are passed, not direct values. 调用
scanf
,会传递指针,而不是直接值。 A pointer to float
is not converted to a pointer to double
(this could not work since the pointed-to object cannot change when you change the pointer type). 指向
float
的指针不会转换为指向double
的指针(由于指向对象在更改指针类型时无法更改,因此无法工作)。 So, for scanf
, the argument for %f
must be a pointer to float
, and the argument for %lf
must be a pointer to double
. 因此,对于
scanf
, %f
的参数必须是指向float
的指针,而%lf
的参数必须是指向double
的指针。
As far as I read manual pages, scanf says that 'l' length modifier indicates (in case of floating points) that the argument is of type double rather than of type float, so you can have 'lf, le, lg'. 至于我阅读手册页,scanf说'l'长度修饰符指示(在浮点的情况下)参数是double类型而不是float类型,所以你可以有'lf,le,lg'。
As for printing, officially, the manual says that 'l' applies only to integer types. 至于打印,正式,手册说'l'仅适用于整数类型。 So it might be not supported on some systems or by some standards.
因此,某些系统或某些标准可能不支持它。 For instance, I get the following error message when compiling with
gcc -Wall -Wextra -pedantic
例如,在使用
gcc -Wall -Wextra -pedantic
编译时,我收到以下错误消息
a.c:6:1: warning: ISO C90 does not support the ‘%lf’ gnu_printf format [-Wformat=]
So you may want to doublecheck if your standard supports the syntax. 因此,如果您的标准支持语法,您可能需要重新检查。
To conclude, I would say that you read with '%lf' and you print with '%f'. 总而言之,我会说你用'%lf'阅读并用'%f'打印。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.