首先发生什么,截断或评估?如果我这样做:
int a = (2+3)*10.5;
a得到52,但如果我这样做:
int a = 30 / 4 * 5;
a得到35。
因此首先评估表达式然后进行截断。然后截断的值用于其他计算? '导致第二个陈述" 30/4"首先进行评估,然后将其截断为7.具体的规则是什么?文档中的任何内容......我不是在谈论类型转换,只是在这种情况下截断,就像表达式一个接一个地被截断?
答案 0 :(得分:5)
您提出错误的问题,没有单独的评估和截断步骤。截断是类型转换的副作用,如果转换后的值无法准确表示在目标类型中,例如
double d = 2.5;
int i = d; // 2.5 is truncated as a side effect of converting to int
所以你必须知道的是在评估表达式时如何转换操作数。确切的规则有点复杂,我将重点关注这里的基础知识。通常,对于算术运算符,如果操作数不具有相同的类型,则其中一个以某种方式转换,因此可以表示这两个值。在你的第一个例子中:
int a = (2+3)*10.5;
2
和3
都属于int
类型,因此只需添加它们 - 结果(5
)的类型为int
试。
但10.5
的类型为double
。因此,5
也会转换为double
,结果为52.5
。只是因为您将其分配给int
,它才会转换回int
,因此必须进行截断。
在你的第二个例子中:
int a = 30 / 4 * 5;
30
和4
都有int
类型。因此,不进行转换,直接进行分割。
以下是捕获:划分两个整数是一个整数除法,这再次导致int
(此处:7
)。这不是截断,它只是如何定义整数除法。实际上,您可能在学校早期使用名为long division with remainder的算法了解了该操作。有一个"对面" C中的操作模(%
),它将为您提供该部门的余数。
因此,您在此处获得7
类型的结果int
,然后乘以5
,再乘以int
,因此,再次,没有转化 - 最终结果是35
。
检查如果写
会发生什么int a = 30.0 / 4 * 5;
代替。现在,/
的第一个操作数是双精度数,因此4
也会转换为double
,结果为7.5
- 这也是double
},导致5
转换为double
并产生37.5
的最终结果。
这又转换为int
,因为您将其分配给int
并截断产生37
。
注意运算符/
在这里意味着两个不同的东西(真正的除法与整数除法),具体取决于其操作数的类型。
答案 1 :(得分:4)
发生的情况取决于所涉及的值的类型。
2
,3
,30
,4
和5
都属于int
类型。
10.5
的类型为double
。
因此(2+3)*10.5
执行2
和3
的整数加法,产生5
(另一个int
),然后5.0
的浮点乘法(隐式转换自5
)和10.5
,产生52.5
。此号码已分配给int
,隐式将其截断为52
。
另一方面,在30 / 4 * 5
中,所有操作数均为int
,并且没有任何内容转换为double
。因此30 / 4
执行整数除法,产生7
,然后乘以5
,产生35
。
没有单独的评估和截断。截断可以作为类型转换的一部分发生,但在30 / 4
中,您不是在考虑单独的截断和评估步骤,而是单个操作(整数除法)。当然,由于此结果的类型为int
,因此不能包含任何小数位。
答案 2 :(得分:2)
不要考虑截断和评估。相反,请考虑分组和整数除法。还有一些其他术语需要引入才能进行充分的分析:我已经注意 italicise 那些。
由于括号,表达式 (2 + 3) * 10.5
被明确分组。所以5 * 10.5
是一个中间步骤;这是double
类型,5
从int
转换为double
。此表达式的值为52.5
,在分配给52
时会被截断为int
。
30 / 4 * 5
从左到右分组(乘法和除法具有相同的优先级,因此运算符的关联性来自进入游戏),所以它相当于(30 / 4) * 5
。 30 / 4
为7
(整数除法),并乘以5
以获得结果。
一个更有趣的例子是30 / 4 * 5.0
。那是仍然 35
但是double
类型。分组仍为(30 / 4) * 5.0
。