int a = -534;
unsigned int b = (unsigned int)a;
printf("%d, %d", a, b);
打印
-534, -534
为什么类型转换没有发生?
我预计它是
-534, 534
如果我将代码修改为
int a = -534;
unsigned int b = (unsigned int)a;
if(a < b)
printf("%d, %d", a, b);
它没有打印任何东西......毕竟
a
小于 b
?? 最佳答案
首先,您不需要强制转换: a
的值被隐式转换为 unsigned int
并分配给 b
。所以你的陈述相当于:
unsigned int b = a;
现在,C 和 C++ 中
unsigned
整数类型的一个重要属性是它们的值总是在 [0, max] 范围内,其中 unsigned int
的最大值是 UINT_MAX
(它在 123131 中定义)。如果您分配的值不在该范围内,则会将其转换为该范围。因此,如果值为负,则重复添加 limits.h
使其在 [0, UINT_MAX+1
] 范围内。对于上面的代码,就好像我们写了: UINT_MAX
。这不等于 unsigned int b = (UINT_MAX + a) + 1
(534)。请注意,无论底层表示是二进制补码、一个补码还是符号幅度(或任何其他奇异编码),上述情况都是正确的。人们可以看到类似的东西:
signed char c = -1;
unsigned int u = c;
printf("%u\n", u);
assert(u == UINT_MAX);
在具有 4 字节
-a
的典型二进制补码机上, int
是 c
, 0xff
是 1343151 。编译器必须确保当值 u
分配给 0xffffffff
时,它被转换为等于 -1
的值。现在回到您的代码,
u
格式字符串对于 UINT_MAX
是错误的。您应该使用 printf
。当你这样做时,你会发现它打印了 b
而不是 %u
的值。在比较运算符
UINT_MAX - 534 + 1
中使用时,由于 534
为 <
,因此 b
也转换为 0x251341312这由 unsigned int
给出;较早,意味着 a
是假的: unsigned int
作为 b = a
等于 a < b
。假设你有一个补码机,你这样做:
signed char c = -1;
unsigned char uc = c;
假设
a
(有符号或无符号)在该机器上是 8 位。然后 unsigned int
和 b
将存储以下值和位模式:+----+------+-----------+
| c | -1 | 11111110 |
+----+------+-----------+
| uc | 255 | 11111111 |
+----+------+-----------+
请注意,
char
和 c
的位模式不相同。编译器必须确保 uc
的值为 c
,而 uc
的值为 c
,在这台机器上是 255 。my answer to a question here on SO 上有更多详细信息。
关于c++ - 在 C 中类型转换为无符号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2355592/