简体   繁体   English

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

[英]why result of (double + int) is 0 (C language)

result of 的结果

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

is 0 是0

but

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

is 7 是7

What's the difference between the two? 这两者有什么区别?

The result of 5.0 + 2 is 7.0 and is of type double . 5.0 + 2的结果是7.0并且是double类型。

The "%d" format is to print int . "%d"格式是打印int

Mismatching format specification and argument type leads to undefined behavior . 不匹配的格式规范和参数类型会导致未定义的行为

To print a float or double value with printf you should use the format "%f" . 要使用printf打印floatdouble值,您应使用格式"%f"


With

int num = 5.0 + 2;

you convert the result of 5.0 + 2 into the int value 7 . 您将5.0 + 2的结果转换为int7 Then you print the int value using the correct format specifier. 然后使用正确的格式说明符打印int值。

In all expressions, every operand has a type. 在所有表达式中,每个操作数都有一个类型。 5.0 has type double . 5.0double类型。 2 has type int . 2int类型。

Whenever a double and an integer are used as operands of the same operator, the integer is silently converted to a double before calculation. 只要double和integer用作同一运算符的操作数,整数就会在计算之前以无提示方式转换为double。 The result is of type double . 结果是double类型。

And so you pass double to printf , but you have told it to expect an int , since you used %d . 因此你将double传递给printf ,但是你告诉它期望一个int ,因为你使用了%d The result is a bug, the outcome is not defined. 结果是一个错误,结果没有定义。

But in case of int num = 5.0 + 2; 但是在int num = 5.0 + 2;情况下int num = 5.0 + 2; , you first get a result as double , 7.0 . ,你首先得到一个double的结果, 7.0 Then force a conversion back to int . 然后强制转换回int That code is equivalent to: 该代码相当于:

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

More details here: Implicit type promotion rules 更多细节: 隐式类型促销规则

The result of expression 5.0 + 2 is of type double , since at least one of the two operands of operator + here is a floating point / double value (so the other one will be converted to double before adding). 表达式5.0 + 2的结果是double类型,因为operator +的两个操作数中的至少一个是浮点/双值(因此另一个将在添加之前转换为double )。

If you write printf("%d\\n", 5.0 + 2) , you will pass a floating point value where the format specifier actually expects an int . 如果你编写printf("%d\\n", 5.0 + 2) ,你将传递浮点值,格式说明符实际上需要一个int This mismatch is undefined behaviour, and the 0 you receive could be something else (another number, a crash, a .... what ever), too. 这种不匹配是未定义的行为,你收到的0可能是其他东西(另一个数字,崩溃,......什么都有)。

int num = 5.0 + 2 , in contrast, will convert the double -value resulting from 5.0 + 2 back to an integral value (discarding any fractional part). 相反, int num = 5.0 + 2会将5.0 + 2产生的double值转换回积分值(丢弃任何小数部分)。 So the value of num will be 7 and will be - since num is an integral type - valid in conjunction with format specifier %d then. 所以num的值将是7并且将是 - 因为num是一个整数类型 - 然后与格式说明符%d一起有效。

5.0+2 is typed double . 5.0+2是键入的double

The compiler warning for 编译器警告

int main() { return _Generic(5.0 + 2, struct foo: 0); }

should tell you as much if 应该告诉你多少

int main() { return _Generic(5.0 + 2, double: 5.0+2); }

compiling without error doesn't. 编译没有错误没有。

Matching "%d" with a double in printf results in undefined behavior. 匹配"%d"printfdouble导致未定义的行为。

Any result is legal, including your harddrive getting erased (unlikely to happen unless your program already has such functionality somewhere in it; if it does, UB can well result it it being inadvertently invoked). 任何结果都是合法的,包括你的硬盘被删除(除非你的程序已经在其中某处具有这样的功能,否则不太可能发生;如果是,UB很可能导致它被无意中调用)。

The usual arithmetic conversions are implicitly performed to cast their values to a common type. 隐式执行通常的算术转换以将其值转换为公共类型。 The compiler first performs integer promotion; 编译器首先执行整数提升; if the operands still have different types, then they are converted to the type that appears highest in the following hierarchy - 如果操作数仍然具有不同的类型,则它们将转换为在以下层次结构中显示最高的类型 -

在此输入图像描述

In int num = 5.0 + 2; int num = 5.0 + 2; this code snippet you are adding a float with integer and storing back to integer again. 这段代码片段是你添加一个带整数的浮点数并再次存回整数。 So, c automatically casts the result into integer to store in an integer type variable. 因此,c自动将结果转换为整数以存储在整数类型变量中。 So, while printing using %d, it prints fine. 因此,在使用%d打印时,打印效果很好。

But, in printf("%d\\n", 5.0 + 2); 但是,在printf("%d\\n", 5.0 + 2); this code snippet, the addition is casted into floating point number as float has higher priority over integer, but you are printing it using %d. 这段代码片段,加法被转换为浮点数,因为float优先于整数,但是你使用%d打印它。 Here mismatch of format specifier causing the unexpected result. 这里格式说明符不匹配导致意外结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM