【发布时间】:2019-01-31 12:06:31
【问题描述】:
结果
printf("%d\n", 5.0 + 2);
是0
但是
int num = 5.0 + 2;
printf("%d\n", num);
是 7
两者有什么区别?
【问题讨论】:
-
参考这个答案它会帮助更多stackoverflow.com/a/9027033/7865621
结果
printf("%d\n", 5.0 + 2);
是0
但是
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 值。
【讨论】:
printf("%d\n", 1.1 ); 的结果是垃圾值 printf("%d\n", 5.0 ); 的结果是 0 两者有什么区别?非常感谢您的回复。
在所有表达式中,每个操作数都有一个类型。 5.0 的类型为 double。 2 的类型为 int。
当双精度和整数用作同一运算符的操作数时,整数会在计算前静默转换为双精度。结果是double 类型。
所以你将double 传递给printf,但你告诉它期待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 会将double-值从5.0 + 2 转换回整数值(丢弃任何小数部分)。所以num 的值将是7 并且将是 - 因为num 是一个整数类型 - 然后与格式说明符%d 一起有效。
【讨论】:
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); }
编译没有错误不会。
将"%d" 与double 中的printf 匹配会导致未定义的行为。
任何结果都是合法的,包括您的硬盘被擦除(除非您的程序已经在其中某处具有此类功能,否则不太可能发生这种情况;如果确实如此,UB 很可能导致它被无意中调用)。
【讨论】: