C 求值与截断
首先发生什么,截断还是求值?如果我这样做:C 求值与截断,c,truncation,C,Truncation,首先发生什么,截断还是求值?如果我这样做: int a = (2+3)*10.5; int a = 30 / 4 * 5; a得到52,但如果我这样做: int a = (2+3)*10.5; int a = 30 / 4 * 5; a得35分 因此,表达式首先求值,然后被截断。然后将截断的值用于其他计算?”第二条语句中的原因“30/4”首先被计算,然后被截断为7。具体的规则是什么?文档中的任何内容。。。我不是说类型转换,只是在这种情况下截断,就像表达式一个接一个地被截断一样?发生什
int a = (2+3)*10.5;
int a = 30 / 4 * 5;
a得到52,但如果我这样做:
int a = (2+3)*10.5;
int a = 30 / 4 * 5;
a得35分
因此,表达式首先求值,然后被截断。然后将截断的值用于其他计算?”第二条语句中的原因“30/4”首先被计算,然后被截断为7。具体的规则是什么?文档中的任何内容。。。我不是说类型转换,只是在这种情况下截断,就像表达式一个接一个地被截断一样?发生什么取决于所涉及的值的类型
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
s,没有任何操作数转换为double
。因此,30/4
执行整数除法,得到7
,然后乘以5
,得到35
没有单独的求值和截断。截断可以作为类型转换的一部分进行,但在
30/4
中,您看到的不是单独的截断和求值步骤,而是单个操作(整数除法)。当然,因为这个结果的类型是int
,所以它不能有任何小数位。你问错了问题,没有单独的求值和截断步骤。如果转换后的值不能在目标类型中准确表示,则截断是类型转换的副作用,如
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
类型。因此,不进行转换,直接进行分割
这里有一个问题:将两个整数除法是一个整数除法,它再次导致整数
(这里:7
)。这不是截断,而是整数除法的定义。事实上,你可能在学校的早期就知道了这个操作,使用了一种叫做。在C中有一个“相反”的模运算(%
),它将为您提供该除法的剩余部分
因此,这里有类型为int
的结果7
,然后乘以5
,再乘以另一个int
,因此,同样没有转换——最终结果是35
检查如果你写了会发生什么
int a = 30.0 / 4 * 5;
相反。现在,/
的第一个操作数是双精度的,因此4
也被转换为double
,结果是7.5
——这也是double
,导致5
转换为double
,并产生37.5
的最终结果
这将再次转换为int
,因为您将其分配给int
,截断将产生37
请注意,运算符
/
在这里表示两种不同的含义(实数除法与整数除法),具体取决于其操作数的类型。不要考虑截断和求值。相反,考虑分组和整数除法。为了进行充分的分析,还需要引入一些其他术语:我已注意将这些术语斜体化
表达式(2+3)*10.5
因括号而显式分组。所以5*10.5
是一个中间步骤;这是一种double
类型,因为5
从int
转换为double
。此表达式的值为52.5
,当分配给int
时,该值被截断为52
30/4*5
从左到右分组(乘法和除法具有相同的优先级,因此运算符的关联性发挥作用),因此它相当于(30/4)*5
30/4
是7
(整数除法),然后乘以5
得到结果
一个更有趣的例子是
30/4*5.0
。这仍然是35
,但属于double
类型。分组保持为(30/4)*5.0
使用运算符优先级扣除数据类型。。。。如果/
和*
具有相同的优先级和左关联性,它们将作为(30/4)*5执行,不是吗<代码>30/4=>7
和7*5=>35
。对吗?不进行截断,将两个整数相除,得到一个int
结果。试试30.0/4*5
,看看会发生什么。