result of
printf("%d\n", 5.0 + 2);
is 0
but
int num = 5.0 + 2;
printf("%d\n", num);
是7
这两者之间有什么区别?
5.0 + 2
的结果是 7.0
,类型为 double
。
"%d"
格式用于打印 int
。
格式说明符和参数类型不匹配会导致未定义的行为。
要使用printf
打印float
或double
值,应使用格式"%f"
。
使用
int num = 5.0 + 2;
5.0 + 2
的结果转换为 int
值 7
。然后使用正确的格式说明符打印出这个 int
值。在所有表达式中,每个操作数都有一个类型。 5.0
的类型是 double
,2
的类型是 int
。
无论何时,当一个双精度和一个整数被用作同一运算符的操作数时,在计算之前,整数将被静默转换为双精度。结果的类型为 double
。
所以,你向 printf
传递了一个 double
,但是你告诉它期望一个 int
,因为你使用了 %d
。结果就是一个错误,其结果未定义。
但在 int num = 5.0 + 2;
的情况下,你首先得到一个 double
结果,即 7.0
。然后强制将其转换回 int
。该代码相当于:
int num = (int)((double)5.0 + (double)2);
更多细节请参见:隐式类型提升规则
5.0 + 2
的结果是 double
类型,因为运算符 +
的两个操作数中至少有一个是浮点数/双精度值(所以另一个将在加法之前转换为 double
)。printf("%d\n", 5.0 + 2)
,则会将一个浮点值传递到格式说明符实际上期望的 int
中。这种不匹配是未定义行为,您收到的 0
可能是其他数字,崩溃或其他任何东西。int num = 5.0 + 2
将把从 5.0 + 2
得出的 double
值转换回整数值(丢弃任何小数部分)。因此,num
的值将为 7
,并且将与格式说明符 %d
结合使用时有效,因为 num
是整数类型。5.0+2
is typed double
."的英译中:
5.0+2
被输入为double
。
对于编译器警告:
int main() { return _Generic(5.0 + 2, struct foo: 0); }
int main() { return _Generic(5.0 + 2, double: 5.0+2); }