将负值分配给unsigned int时会发生什么?

n0n*_*hun 14 c unsigned

可能重复:
在C中签名为无符号转换 - 它总是安全吗?

假设我声明了unsigned int类型的变量: unsigned int x = -1;

现在-1的二进制补码(假设32位机器)为0xFFFFFFFF.现在,当我将此值赋给x时,值0x7FFFFFFF是否已分配给x?

如果是这样,则printf("%d",x); 会打印十进制等效的0x7FFFFFFF,对吧?但是,显然这没有发生,因为打印的值是-1.我在这里错过了什么?

编辑:我知道我们可以使用%u格式说明符来打印无符号值.但这无助于回答上述问题.

Kei*_*son 21

"%d"格式是(signed)int的值.如果使用无符号值,则可以打印除实际值以外的值.使用"%u"看实际值,或者%x看到它在十六进制.

在宣言中

unsigned int x = -1;
Run Code Online (Sandbox Code Playgroud)

表达式-1的类型为int,其值为-1.初始值设定项将此值从int转换为unsigned int.签名到无符号转换的规则表示该值以模数减少UINT_MAX + 1,因此-1将转换为UINT_MAX(可能0xffffffff或者4294967295如果unsigned int是32位).

您根本无法将负值分配给无符号类型的对象.在分配之前,任何此类值都将转换为无符号类型,结果将始终> = 0.

  • @ n0nChun:这不是负数可以表示的唯一方法.二进制补码是最常用的方法; 其他是1s'补充和符号和大小(C标准允许所有三个).而关键是你实际上*不能*给unsigned int赋一个负值; 任何负值都将被隐式转换,从而产生非负无符号值.此外,`unsigned int`不一定是32位; 它可以小到16位.`-1`将始终转换为`UINT_MAX`,这不一定是`0xffffffff`. (2认同)
  • @Daniel:2倍大*加1*。 (2认同)

Era*_*man 6

使用%u而不是%d为了打印无符号值.然后你应该看到0xFFFFFFFF.