C++和无符号类型

C++ and unsigned types

本文关键字:类型 无符号 C++      更新时间:2023-10-16

我正在阅读C++入门第5版,我不明白以下部分:

在无符号类型中,所有位都表示值。例如,8 位 无符号 char 可以保存 0 到 255(含 0 和 255(的值。

"所有位都代表值"是什么意思?

您应该将其与signed类型进行比较。在signed值中,一个位(顶部位(用于指示该值是正数还是负数,而其余位用于保存该值。

简单可复制类型的对象的值由其中的某些位确定,而其他位则不影响其值。在C++标准中,不影响值的位称为填充位

例如,考虑一个具有 8 位的类型,其中最后 4 位是填充位,则由 00000000 和 00001111 表示的对象具有相同的值,并且比较相等。

实际上,填充位通常用于对齐和/或错误检测。

了解了上面的知识,你就可以理解这本书在说什么。它说无符号类型没有填充位。但是,这种说法是错误的。事实上,该标准只保证unsigned char(signed charchar(没有填充位。以下是标准[basic.fundamental]/1相关部分的引用:

对于窄字符类型,对象表示形式的所有位都参与值表示形式。

此外,C11标准6.2.6.2/1说

对于无符号字符以外的无符号整数类型,对象表示的位应分为两组:值位和填充位(不需要任何后者(。

这意味着所有 8 位都表示实际值,而在有符号字符中,只有 7 位表示实际值,第 8 位(最重要的(表示该值的符号 - 正或负 (+/-(。

例如,一个字节包含 8 位,所有 8 位都用于从 0 开始计数。

对于无符号,所有位 0 = 00000000 表示 0,00000001 = 1,00000010 = 2,00000011 = 3,...最多 11111111 = 255。对于有符号
字节(或有符号字符(,最左边的位表示符号,因此不能用于计数。(我正在光学上分离最左边的位!0 0000001 = 1,但 1 0000001 = -1,0 0000010 = 2,1 0000010 = -2,依此类推,最大为 0 1111111 = 127,1 1111111 = -127。在此示例中,1 0000000 表示 -0,这是无用/浪费的,因此它可以表示例如 128。

还有其他方法可以将位编码成数字,有些计算机从左边开始,而不是从右边开始。这些细节是特定于硬件的,与理解"无符号"无关,只有当您想用单个位弄乱代码时,您才需要关心这一点(不推荐(。

这主要是理论上的事情。在实际硬件上,signed整数也是如此。显然,对于有符号整数,其中一些值是负数。

回到unsigned- 文本所说的基本上是无符号数字的值只是 1<<0 + 1<<1 + 1<<2 + ...最多为总位数。重要的是,不仅所有位都有贡献,而且所有位的组合都形成一个有效的数字。signed整数的情况并非如此。因此,如果需要位掩码,它必须是足够宽度的unsigned类型,否则可能会遇到无效的位模式。