关于C中的转换说明符
我对C中的转换说明符有一个问题 在第五句中,如果我使用关于C中的转换说明符,c,format-specifiers,C,Format Specifiers,我对C中的转换说明符有一个问题 在第五句中,如果我使用%lf或%lf而不是%f,则不会发生错误。但是如果我使用%f,为什么会发生错误呢 #include <stdio.h> int main(void) { long double num; printf("value: "); scanf("%f",&num); // If I use %lf or %Lf instead of %f, no error occurs. printf("
%lf
或%lf
而不是%f
,则不会发生错误。但是如果我使用%f
,为什么会发生错误呢
#include <stdio.h>
int main(void)
{
long double num;
printf("value: ");
scanf("%f",&num); // If I use %lf or %Lf instead of %f, no error occurs.
printf("value: %f \n",num);
}
#包括
内部主(空)
{
长双数;
printf(“值:”);
scanf(“%f”,&num);//如果使用%lf或%lf而不是%f,则不会发生错误。
printf(“值:%f\n”,num);
}
%f
用于读取浮点
s,而不是双精度
s或长双精度
s
%lf
用于读取double
s
%Lf
用于读取long double
s
如果您的程序在变量类型为长双精度时使用
%lf
,这只是巧合。这可能是因为sizeof(double)
与平台上的sizeof(long double)
相同。理论上,这是一种未定义的行为。%f
用于读取浮点
s,而不是双精度
s或长双精度
s
%lf
用于读取double
s
%Lf
用于读取long double
s
如果您的程序在变量类型为长双精度时使用
%lf
,这只是巧合。这可能是因为sizeof(double)
与平台上的sizeof(long double)
相同。理论上,这是未定义的行为。在查看FreeBSD系统(顺便说一句,它是POSIX)上的printf(3)
手册页时,我得到以下信息:
以下长度修饰符适用于a
、a
、e
、e
、f
、f
、g
,
或G
转换:
Modifier a, A, e, E, f, F, g, G
l (ell) double (ignored, same behavior as without it)
L long double
我使用了32位浮点数据类型的转换。但这里的问题是,原因是不同的浮点格式有不同的大小,而printf
函数需要知道它是哪种格式,以便能够正确地进行转换。在浮点上使用%Lf
可能会导致分段错误,因为转换正在访问变量外部的数据,因此会出现未定义的行为
- 浮点:32位
- 双精度:64位
- 长双:80位
不过这里要小心,因为它可能需要128位,但这并不意味着它是一个
\uuu128
(如果使用gcc或clang)。至少有一个平台指定long double
确实意味着\uuu float128
(我认为是SunOS),但它是在软件中实现的,速度很慢。此外,有些编译器(微软和英特尔会想到)long double
=double
,除非您在命令行上指定一个开关。在FreeBSD系统(顺便说一句,是POSIX)上查看printf(3)
的手册页时,我得到以下信息:
以下长度修饰符适用于a
、a
、e
、e
、f
、f
、g
,
或G
转换:
Modifier a, A, e, E, f, F, g, G
l (ell) double (ignored, same behavior as without it)
L long double
我使用了32位浮点数据类型的转换。但这里的问题是,原因是不同的浮点格式有不同的大小,而printf
函数需要知道它是哪种格式,以便能够正确地进行转换。在浮点上使用%Lf
可能会导致分段错误,因为转换正在访问变量外部的数据,因此会出现未定义的行为
- 浮点:32位
- 双精度:64位
- 长双:80位
不过这里要小心,因为它可能需要128位,但这并不意味着它是一个
\uuu128
(如果使用gcc或clang)。至少有一个平台指定long double
确实意味着\uuu float128
(我认为是SunOS),但它是在软件中实现的,速度很慢。此外,有些编译器(Microsoft和Intel会想到)long double
=double
,除非您在命令行上指定了一个开关。所以您会问,如果使用了错误的说明符,为什么会收到编译器警告?请后退一步,再次阅读您的问题。然后,拿一本C书,从第一页开始学习。@Olaf这实际上是一个令人困惑的学习主题,因为%f
指的是printf
vsscanf
@dasblinkenlight:中的不同之处,在我自己的函数中,它可能意味着更大的不同。无论如何,这是关于长双精度的,没有区别printf
acceptiondouble
for%f
只是一个遗留问题,因为您无法将float
参数传递给可变函数。在我看来,这是直截了当的。在两个函数中(logn double
已清除),只要对float
参数使用%f
,对double
参数使用%lf
即可。对我来说这听起来不是很混乱。所以你问如果你使用了错误的说明符为什么会得到编译器警告?请后退一步,再次阅读您的问题。然后拿一本C语言书,从第一页开始学习。@Olaf T