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

问题描述 投票:0回答:3

下面的C++代码是什么意思?

unsigned char a : 1; 
unsigned char b : 7;

我猜它创建了两个字符 a 和 b,它们都应该是一个字节长,但我不知道“:1”和“:7”部分是做什么的。

c++ c bit-fields
3个回答
73
投票

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常量表达式

指定一个位域;它的长度由冒号与位域名称分开。可选的 attribute-specifier 适用于被声明的实体。位域属性不是类成员类型的一部分。

constant-expression 应为整数常量表达式,其值大于或等于零。整数常量表达式的值可能大于位域类型的对象表示中的位数;在这种情况下,额外的位用作填充位并且不参与位字段的值表示。

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

注意: 位域跨越某些机器上的分配单元,而不是其他机器上的。位字段在某些机器上是从右到左分配的,在其他机器上是从左到右分配的。 - 尾注


9
投票

我相信那些将是位域。


1
投票

严格来说,位域必须是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:

如果剩余足够的空间,一个位域 结构中紧跟在另一个位域之后的应该被打包 到同一单元的相邻位。如果剩余空间不足, 是否将不适合的位域放入下一个单元或 重叠相邻单元是实现定义的。

© www.soinside.com 2019 - 2024. All rights reserved.