以下程序应该读取一个浮点数,然后打印一个整数。但是当我运行它时,它不会打印整数。而是打印我在scanf
中输入的值。
任何人都可以解释输出吗?
#include<stdio.h>
void main()
{
long x;
float t;
scanf("%f",&t);
printf("%d\n",t);
x=90;
printf("%f\n",x);
{
x=1;
printf("%f\n",x);
{
x=30;
printf("%f\n",x);
}
x=9;
printf("%f\n",x);
}
}
答案 0 :(得分:3)
t
的类型为float
,因此printf("%d\n",t)
会调用未定义的行为,因为%d
需要类型为int
的参数。任何事情都可能发生。 (printf("%f\n",x)
也是如此:%f
期望double
,但x
的类型为long int
。)
我曾回答其中一个案例in detail;也许这有点兴趣。结果是,在实践中,您可以通过研究IEEE754浮点数的解剖结构,以及了解平台上整数类型的大小来解释观察到的行为。
答案 1 :(得分:1)
打印%d
变量时应使用int
,如下所示:
printf("%ld", x);
您正在使用%f
。
答案 2 :(得分:1)
printf("%f\n",x);
x
的类型为long
,但%f
转换器需要一个浮点值(类型为double
)。通常,当您将整数传递给期望浮点值的函数时,将以静默方式转换该值。但是,这仅适用于具有固定数量参数的函数和指示每个参数类型的原型。它不适用于printf
等可变函数,因为编译器没有足够的信息来知道将值转换为什么:格式字符串只能在运行时进行分析。
语言规范使该程序的行为不确定:它可以做任何事情。在这种情况下可能发生的是x
存储在某个整数寄存器中,f
存储在某个浮点寄存器中。由于printf
调用正在寻找浮点值,因此编译后的代码将查找第一个浮点寄存器。如果您已将浮点值传递给printf
,则该参数将最终出现在该寄存器中。但是你没有,所以该寄存器中的值是存储在那里的最后一个值:scanf
读取的值。
一个好的编译器会警告你,你做错了什么。例如,这是我用gcc -O -Wall
编译代码时得到的结果:
a.c:2: warning: return type of 'main' is not 'int'
a.c: In function 'main':
a.c:7: warning: format '%d' expects type 'int', but argument 2 has type 'double'
a.c:9: warning: format '%f' expects type 'double', but argument 2 has type 'long int'
a.c:12: warning: format '%f' expects type 'double', but argument 2 has type 'long int'
a.c:15: warning: format '%f' expects type 'double', but argument 2 has type 'long int'
a.c:18: warning: format '%f' expects type 'double', but argument 2 has type 'long int'
我建议您配置编译器以打印此类警告并注意它们。
要使程序正常工作,要么将浮点值传递给期望的值,要么告诉printf
期望一个整数值。任
printf("%f", (double)x);
或
printf("%ld", x);
答案 3 :(得分:0)
x是一个长整数,但你将它打印为浮点数。并且t是一个浮点数,但你将它打印为整数。在printf调用中切换%d和%f格式说明符。