-4
#include<stdio.h>
#define square(x) x*x

    void main()
    {
        int i;
        i = 8 / square(4);
        printf("%d %d", i, 8/square(4));
    }

给出输出:8 8

但如果我写下面的代码:

#include<stdio.h>
#define square(x) x*x

    void main()
    {
        float i;
        i = 8 / square(4);
        printf("%f %f", i, 8/square(4));
    }

给出输出:8.000000 0.000000

为什么会这样???请解释

4

6 回答 6

2

问题不仅在于格式说明符,还在于您定义宏的方式。它应该是:

#define square(x) ((x)*(x))

宏也不是类型安全的。现在,如果您转换结果,您将看到发生了什么,因为 4 的平方是 16,而 8/16 是 0.5,它会被截断为int0。对于正确的值,这就是您应该如何进行类型转换:

printf("%d %d", (int)i, (int)(8/square(4)));
printf("\n%f %f", (float)i, (float)8/((float)square(4)));

样本输出

0 0
0.000000 0.500000
于 2013-11-13T06:40:23.617 回答
1

首先纠正这个:

#define square(x) x*x

#define square(x) ((x)*(x))

宏替换后的正确结果。

现在,在您的第一个程序中,正如其他人所解释的那样,您使用错误%f的格式说明符来打印整数(8/(square(4)将评估为整数),这是未定义的行为。

在第二个程序中,8/square(4)float您将结果存储在float i. 因此,您可以8.000000进行第一次打印。在第二次打印时,由于与上述相同的原因,结果是错误的。

于 2013-11-13T06:36:53.523 回答
0

因为 %f 表示数字的类型是双精度和默认精度

于 2013-11-13T07:18:14.153 回答
0

第一个很容易理解,所以我只关注第二个。您将 %f 用于需要浮点数的第二个参数,而 C 编译器将 8/square(4) 作为整数。这种不匹配会破坏您的结果。

于 2013-11-13T06:13:16.697 回答
0

8/square(4)结果到一个int并尝试使用%fis Undefined behavior打印一个整数。所以在第二种情况下调试你得到的值是没有用的。

如果您使用的是 gcc 编译器,那么命令cc -E filename.c可能会澄清您的疑虑。

于 2013-11-13T06:17:55.993 回答
0

这是因为您在第二个程序中将 float 作为数据类型。

8/square(4) 将给出一个整数结果,因此您的输出会出错。您使用 %f 打印一个整数。

就是这么简单...

于 2013-11-13T06:23:47.287 回答