#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
为什么这样?请解释
答案 0 :(得分:2)
问题不仅在于格式说明符,还在于您定义宏的方式。它应该是:
#define square(x) ((x)*(x))
宏也不是类型安全的。现在,如果您投射结果,您将看到正在发生的事情,因为4的平方是16而8/16是0.5,它被截断为int
因此变为0.对于正确的值,这是你应该如何进行类型转换:< / p>
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
答案 1 :(得分:1)
首先纠正这个:
#define square(x) x*x
到
#define square(x) ((x)*(x))
在宏替换后获得正确的结果。
现在,在您的第一个程序中,正如其他人所解释的那样,您使用了错误的格式说明符%f
来打印整数(8/(square(4)
将计算为整数),这是未定义的行为。
在第二个程序中,当您将结果存储在8/square(4)
时,float
的类型已提升为float i
。因此,您在首次打印时获得8.000000
。在第二次打印时,由于与上述相同的原因,结果是错误的。
答案 2 :(得分:0)
第一个很容易理解所以我只专注于第二个。您使用%f作为第二个参数,它需要一个浮点数,而C编译器将8 / square(4)作为整数。这种不匹配会破坏你的结果。
答案 3 :(得分:0)
8/square(4)
结果为int
,尝试使用%f
打印整数为Undefined behavior。因此,没有使用调试第二种情况下的值。
如果您正在使用gcc编译器,那么命令cc -E filename.c
可能会澄清您的疑虑。
答案 4 :(得分:0)
这是因为你在第二个程序中给了float作为数据类型。
8 / square(4)将给出整数结果,因此输出错误。你使用%f来打印一个整数。
这很简单......
答案 5 :(得分:0)
因为%f表示数字类型是double和默认精度