为什么(double + int)的结果为0(C语言)

时间:2019-01-31 12:06:32

标签: c int double

结果

printf("%d\n", 5.0 + 2);

是0

但是

int num = 5.0 + 2;
printf("%d\n", num);

是7

两者之间有什么区别?

5 个答案:

答案 0 :(得分:9)

5.0 + 2的结果为7.0,类型为double

"%d"格式将打印int

格式规范和参数类型不匹配会导致不确定的行为

要使用printf打印floatdouble值,应使用格式"%f"


使用

int num = 5.0 + 2;

您将5.0 + 2的结果转换为int7。然后,使用正确的格式说明符打印int值。

答案 1 :(得分:6)

在所有表达式中,每个操作数都有一个类型。 5.0的类型为double2的类型为int

每当将double和整数用作同一运算符的操作数时,在计算之前,该整数将被静默转换为double。结果的类型为double

因此您将double传递给printf,但是由于使用了int,因此您已经告诉它期望%d。结果是错误,结果未定义。

但是对于int num = 5.0 + 2;,您首先得到的结果为double7.0。然后,将转换强制返回到int。该代码等效于:

int num = (int)((double)5.0 + (double)2);

此处有更多详细信息:Implicit type promotion rules

答案 2 :(得分:3)

表达式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一起有效。

答案 3 :(得分:1)

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很可能会导致它被无意中调用)。

答案 4 :(得分:0)

隐式执行通常的算术转换,以将其值转换为通用类型。编译器首先执行整数提升;如果操作数仍然具有不同的类型,则它们将被转换为以下层次结构中显示最高的类型-

enter image description here

int num = 5.0 + 2;的此代码段中,您将添加一个带整数的浮点数,然后再次存储回整数。因此,c自动将结果转换为整数以存储在整数类型变量中。因此,在使用%d打印时,它可以正常打印。

但是,在此代码段的printf("%d\n", 5.0 + 2);中,由于浮点数的优先级高于整数,因此将附加内容强制转换为浮点数,但是您正在使用%d进行打印。这里的格式说明符不匹配会导致意外结果。