C 中的无符号值
Unsigned values in C
我有以下代码:
#include <stdio.h>
int main() {
unsigned int a = -1;
int b = -1;
printf("%x\n", a);
printf("%x\n", b);
printf("%d\n", a);
printf("%d\n", b);
printf("%u\n", a);
printf("%u\n", b);
return 0;
}
输出为:
ffffffff
ffffffff
-1
-1
4294967295
4294967295
我可以看到根据传递给 printf
函数的值将值解释为有符号或无符号。在这两种情况下,字节都是相同的 (ffffffff
)。那么,unsigned
这个词是干什么用的呢?
在十六进制中不能得到负值。所以它显示为 ffffffff.
使用无符号版本的优点(当您知道包含的值将是非负数时)是有时计算机会为您发现错误(程序将“当负值分配给变量时崩溃”。
在变量声明中使用 unsigned
对程序员本身更有用 - 不要将变量视为负数。正如您所注意到的,-1
和 4294967295
都具有完全相同的 4 字节整数位表示。这完全取决于您想如何对待或看他们。
语句unsigned int a = -1;
将-1
转换成二进制补码,并赋值给a
中的位表示。 printf()
说明符 x
、d
和 u
显示了存储在变量 a
中的位表示在不同格式下的样子。
当你初始化 unsigned int a to -1;
时,这意味着你正在存储 2's
-1
[=36 的补码=] 到 a
.
的内存中
这不过是 0xffffffff
或 4294967295
.
因此,当您使用 %x or %u
格式说明符打印它时,您会得到该输出。
通过指定变量的符号来决定可以存储的值的最小和最大限制。
与unsigned int
一样:范围从0 to 4,294,967,295
和int
:范围从-2,147,483,648 to 2,147,483,647
有关签名的更多信息,请参阅 this
将int -1
分配给unsigned
:由于-1
不在[0...UINT_MAX]
范围内,所以添加UINT_MAX+1
的倍数直到答案在范围内。显然 UINT_MAX
在 OP 的机器上是 pow(2,32)-1 or 429496725
所以 a
的值是 4294967295.
unsigned int a = -1;
"%x"
、"%u"
说明符需要一个匹配的 unsigned
。由于这些不匹配,“如果转换规范无效,则行为未定义。
如果任何参数不是相应转换规范的正确类型,则 行为未定义。”C11 §7.21.6.1 9. printf 说明符不会更改 b
.
printf("%x\n", b); // UB
printf("%u\n", b); // UB
"%d"
说明符需要一个匹配的 int
。由于这些不匹配,更多 UB.
printf("%d\n", a); // UB
给定未定义的行为,不支持结论。
both cases, the bytes are the same (ffffffff).
即使位模式相同,不同的类型也可能有不同的值。 ffffffff
作为 unsigned
的值为 4294967295。作为 int
,取决于有符号整数编码,它的值为 -1、-2147483647 或 TBD。作为 float
它可能是 NAN.
what is unsigned word for?
unsigned
存储 [0 ... UINT_MAX]
范围内的整数。它永远不会有负值。如果代码需要非负数,请使用 unsigned
。如果代码需要一个可以是 +、- 或 0 的计数,请使用 int
.
更新:为了避免将带符号的 int
分配给 unsigned
时出现编译器警告,请使用以下内容。这是一个 unsigned
1u
被否定 - 上面定义明确。效果与 -1
相同,但向编译器传达了直接意图。
unsigned int a = -1u;
我有以下代码:
#include <stdio.h>
int main() {
unsigned int a = -1;
int b = -1;
printf("%x\n", a);
printf("%x\n", b);
printf("%d\n", a);
printf("%d\n", b);
printf("%u\n", a);
printf("%u\n", b);
return 0;
}
输出为:
ffffffff
ffffffff
-1
-1
4294967295
4294967295
我可以看到根据传递给 printf
函数的值将值解释为有符号或无符号。在这两种情况下,字节都是相同的 (ffffffff
)。那么,unsigned
这个词是干什么用的呢?
在十六进制中不能得到负值。所以它显示为 ffffffff.
使用无符号版本的优点(当您知道包含的值将是非负数时)是有时计算机会为您发现错误(程序将“当负值分配给变量时崩溃”。
在变量声明中使用 unsigned
对程序员本身更有用 - 不要将变量视为负数。正如您所注意到的,-1
和 4294967295
都具有完全相同的 4 字节整数位表示。这完全取决于您想如何对待或看他们。
语句unsigned int a = -1;
将-1
转换成二进制补码,并赋值给a
中的位表示。 printf()
说明符 x
、d
和 u
显示了存储在变量 a
中的位表示在不同格式下的样子。
当你初始化 unsigned int a to -1;
时,这意味着你正在存储 2's
-1
[=36 的补码=] 到 a
.
的内存中
这不过是 0xffffffff
或 4294967295
.
因此,当您使用 %x or %u
格式说明符打印它时,您会得到该输出。
通过指定变量的符号来决定可以存储的值的最小和最大限制。
与unsigned int
一样:范围从0 to 4,294,967,295
和int
:范围从-2,147,483,648 to 2,147,483,647
有关签名的更多信息,请参阅 this
将int -1
分配给unsigned
:由于-1
不在[0...UINT_MAX]
范围内,所以添加UINT_MAX+1
的倍数直到答案在范围内。显然 UINT_MAX
在 OP 的机器上是 pow(2,32)-1 or 429496725
所以 a
的值是 4294967295.
unsigned int a = -1;
"%x"
、"%u"
说明符需要一个匹配的 unsigned
。由于这些不匹配,“如果转换规范无效,则行为未定义。
如果任何参数不是相应转换规范的正确类型,则 行为未定义。”C11 §7.21.6.1 9. printf 说明符不会更改 b
.
printf("%x\n", b); // UB
printf("%u\n", b); // UB
"%d"
说明符需要一个匹配的 int
。由于这些不匹配,更多 UB.
printf("%d\n", a); // UB
给定未定义的行为,不支持结论。
both cases, the bytes are the same (ffffffff).
即使位模式相同,不同的类型也可能有不同的值。 ffffffff
作为 unsigned
的值为 4294967295。作为 int
,取决于有符号整数编码,它的值为 -1、-2147483647 或 TBD。作为 float
它可能是 NAN.
what is unsigned word for?
unsigned
存储 [0 ... UINT_MAX]
范围内的整数。它永远不会有负值。如果代码需要非负数,请使用 unsigned
。如果代码需要一个可以是 +、- 或 0 的计数,请使用 int
.
更新:为了避免将带符号的 int
分配给 unsigned
时出现编译器警告,请使用以下内容。这是一个 unsigned
1u
被否定 - 上面定义明确。效果与 -1
相同,但向编译器传达了直接意图。
unsigned int a = -1u;