结构声明中的冒号是什么意思,比如:1,:7,:16,还是:32?

以下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位的值, aa位, b为7位。

通常用于C来访问“压缩”值,如可能包含在8位字符的上半部分中的4位nybble:

 typedef struct { unsigned char leftFour : 4; unsigned char rightFour : 4; } tTwoNybbles; 

对于我们中间的语言律师来说,C ++ 11标准的9.6部分详细解释了这一点,稍微转述一下:


位域[class.bit]

表单的成员声明者

标识符opt属性说明符opt常量表达式

指定一个位域; 它的长度是由冒号的位字段名称引起的。 可选的属性说明符属于被声明的实体。 位字段属性不是类成员类型的一部分。

常量表达式应该是一个大于或等于零的整型常量表达式。 积分常数表达式的值可能大于比特字段类型的对象表示中的比特数; 在这种情况下,额外的比特被用作填充比特并且不参与比特字段的值表示。

类对象中位字段的分配是实现定义的。 位字段的对齐是实现定义的。 位字段被打包成一些可寻址的分配单元。

注意:位域在某些机器上跨越分配单元,而不在其他机器上。 位字段在一些机器上从右到左分配,在其他机器上从左到右分配。 – 结束笔记

我相信这些将是位域。

严格来说,一个位域必须是int,unsigned int或_Bool。 虽然大多数编译器会采取任何整数类型。

Ref C11 6.7.2.1:

位字段的类型应该是_Bool,signed int,unsigned int或其他一些实现定义类型的合格或非限定版本。

您的编译器可能会分配1个字节的存储空间,但是可以免费获取更多。

Ref C11 6.7.2.1:

一个实现可以分配足够大的可寻址存储单元来容纳一个位域。

如果您有多个位域是一个接一个地声明的,那就节省了。 在这种情况下,如果可能,分配的存储将被打包。

Ref C11 6.7.2.1:

如果有足够的空间,紧接在结构中的另一个比特字段之后的比特字段应被打包到相同单元的相邻比特中。 如果剩余空间不足,则将不合适的比特字段放入下一个单元,或与相邻单元重叠是实现定义的。