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 的典型二进制补码机上, intc0xff 是 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 intb 将存储以下值和位模式:
+----+------+-----------+
| c  |  -1  | 11111110  |
+----+------+-----------+
| uc | 255  | 11111111  |
+----+------+-----------+

请注意,charc 的位模式不相同。编译器必须确保 uc 的值为 c ,而 uc 的值为 c ,在这台机器上是 255 。

my answer to a question here on SO 上有更多详细信息。

关于c++ - 在 C 中类型转换为无符号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2355592/

10-15 11:41
查看更多