printf打印由scanf而不是整数参数读取的float

时间:2012-08-15 13:14:27

标签: c printf

以下程序应该读取一个浮点数,然后打印一个整数。但是当我运行它时,它不会打印整数。而是打印我在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);
    }
}

4 个答案:

答案 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格式说明符。