以下 C++ 代码是什么意思?
unsigned char a : 1;
unsigned char b : 7;
我猜它创建了两个字符 a 和 b,它们都应该是一个字节长,但我不知道“:1”和“:7”部分是做什么的。
以下 C++ 代码是什么意思?
unsigned char a : 1;
unsigned char b : 7;
我猜它创建了两个字符 a 和 b,它们都应该是一个字节长,但我不知道“:1”和“:7”部分是做什么的。
1 和 7 是位大小,用于限制值的范围。它们通常出现在结构和工会中。例如,在某些系统上(取决于char
宽度和打包规则等),代码:
typedef struct {
unsigned char a : 1;
unsigned char b : 7;
} tOneAndSevenBits;
创建一个 8 位值,一位为a
, 7 位为b
。
通常在 C 中用于访问“压缩”值,例如 4 位 nybble,它可能包含在 8 位字符的上半部分中:
typedef struct {
unsigned char leftFour : 4;
unsigned char rightFour : 4;
} tTwoNybbles;
对于我们中间的语言律师来说,C++11 标准的 9.6 部分详细解释了这一点,稍微解释一下:
位域 [class.bit]
表单的成员声明符
标识符opt 属性说明符opt : 常量表达式
指定一个位域;它的长度由冒号从位域名称开始。可选的属性说明符属于被声明的实体。位域属性不是类成员类型的一部分。
常量表达式应该是一个整数常量表达式,其值大于或等于零。整数常量表达式的值可能大于位域类型的对象表示中的位数;在这种情况下,额外的位被用作填充位并且不参与位域的值表示。
类对象内的位域分配是实现定义的。位域的对齐是实现定义的。位域被打包到一些可寻址的分配单元中。
注意:位域在某些机器上跨越分配单元,而在其他机器上则不跨越。位域在某些机器上从右到左分配,在其他机器上从左到右分配。-尾注
我相信那些将是位域。
严格来说,位域必须是 int、unsigned int 或 _Bool。尽管大多数编译器将采用任何整数类型。
参考 C11 6.7.2.1:
位域的类型应为 _Bool、signed int、unsigned int 或其他一些实现定义的类型的合格或非合格版本。
您的编译器可能会分配 1 个字节的存储空间,但可以随意获取更多。
参考 C11 6.7.2.1:
实现可以分配任何大到足以容纳位域的可寻址存储单元。
当您有多个位域一个接一个地声明时,就会节省下来。在这种情况下,如果可能,分配的存储空间将被打包。
参考 C11 6.7.2.1:
如果有足够的空间剩余,紧跟在结构中另一个位域之后的位域将被打包到同一单元的相邻位中。如果剩余空间不足,则将不适合的位域放入下一个单元还是与相邻单元重叠是实现定义的。