0

下面的程序应该读取一个浮点数,然后打印一个整数。但是当我运行它时,它不会打印整数。相反,它会打印我输入的值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

4 回答 4

3

t有类型float,所以printf("%d\n",t)调用未定义的行为,因为%d需要一个类型的参数int。任何事情都有可能发生。(对于printf("%f\n",x):也一样,%f需要 a double,但类型xlong int。)

我曾经详细回答过其中一个案例;也许这有点意思。结果是,在实践中,您可以通过研究 IEEE754 浮点数的解剖结构以及了解平台上整数类型的大小来解释观察到的行为。

于 2012-08-15T13:17:52.020 回答
1

您应该%d在打印int变量时使用,如下所示:

printf("%ld", x);

您正在使用%f.

于 2012-08-15T13:18:40.863 回答
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);
于 2012-08-15T13:26:18.860 回答
0

x 是一个长整数,但您将其打印为浮点数。并且 t 是一个浮点数,但您将其打印为整数。在 printf 调用中切换 %d 和 %f 格式说明符。

于 2012-08-15T13:17:51.287 回答