a + b
溢出255回到4,然后c / 2
按预期给出2。但是,为什么在评估相同的两个步骤时,最后一个例子不会溢出?
我猜测内部计算值以更多位存储,然后在执行赋值时仅截断为8位。在那种情况下,哪个是限制,它必须在某个时刻溢出?
uint8_t a = 250;
uint8_t b = 10;
uint8_t c = (a + b);
uint8_t d = c / 2;
uint8_t e = (a + b) / 2;
std::cout << unsigned(c) << ", " << unsigned(d) << ", " << unsigned(e) << "\n";
4,2,130
答案 0 :(得分:2)
它被称为整体推广。操作本身在您的CPU本机整数类型int
中完成,它可以包含大于255的数字。在a+b
情况下,结果必须存储在uint8_t
中,并且&# 39;截断的地方。在最后一种情况下,首先存在一个以int
完成的除法,结果可以完美地存储在uint8_t
中。
答案 1 :(得分:0)
a+b
给出值260,该值未分配给任何uint8_t
类型,因此您在最后一种情况下表现良好。只有当您将任何大于255的值分配给uint8_t
时,才会出现溢出。
答案 2 :(得分:0)
在下面的(a + b)
没有溢出的情况下,编译器会将a
和b
识别为整数类型,因此添加会产生整数类型,此表达式的结果不受表达式中术语或因子的大小。
让我们假设在这种情况下,a
或b
等变量的类型将结果限制为仅该类型。虽然可能使用这样的语言几乎是不可能的。想象一下五个变量,当没有考虑类型时,它们总和为500,即这个......
uint8_t a = 98;
uint8_t b = 99;
uint8_t c = 100;
uint8_t d = 101;
uint8_t e = 102;
以上变量的总和== 500.现在......在下面任何表达式的结果都不能超过其中一个术语的大小......
int incorrect = (a + b + c + d + e);
在这种情况下(a + b + c) == 41
然后(41 + d + e)
== 244.这是一个荒谬的答案..大多数人都认可的替代方案,即
(98 + 99 + 100 + 101 + 102) == 500;
这是存在类型转换的一个原因。
表达式的中间结果不应受表达式中的术语或因素限制,而应受结果类型(即左值)的限制。