【发布时间】:2025-11-23 22:15:01
【问题描述】:
代码:
int main(void) {
uint8_t x = 3;
uint8_t y = 4;
uint8_t z = 5;
uint8_t a = (x - y) / z;
uint8_t b = x - y;
printf("a is %d\n", a);
printf("b is %d\n", b);
return 0;
}
有以下输出:
a is 0
b is 255
我希望(3 - 4) / 5 会导致溢出,因为(3 - 4) 因为uint8_t 是255。当涉及无符号整数的中间步骤导致负数时,为什么它不会溢出?在下一步 / 5 发生之前,(3 - 4) 的结果以什么格式存储?
【问题讨论】:
-
%d不是uint8_t的正确格式说明符。是的,算术运算是使用提升为int的操作数执行的。所以(x-y)实际上会计算为-1并且类型为int。 -
您使用的是哪个编译器?
gcc -Wall作为输出a is 0 b is 255。对于这些值,我也许可以拼凑出一个解释。 -
@EugeneSh。当您在
printf中使用uint8_t时,它会升级为int,因此"%d"应该是正确的说明符。 -
@mch 我不确定。我记得可变参数函数有一个特殊的提升规则
-
其实这里是对 255 和 0 的解释:3-4 = -1,在补码 2 表示中是 255。如果你将 -1 除以某个东西,结果是浮点数,这意味着能够代表否定。如果将其除以大于 1 的值,则结果介于 0 和 -1 之间。如果您将其强制为整数,则会四舍五入为 0。
标签: c integer-overflow unsigned-integer