C 位域
除了结构或联合的成员的声明符外,结构声明符也可以是指定数目的位,称为“位域”。其长度从字段名称的声明符到冒号。 位域被解释为整型类型。
语法
struct-declarator
:
declarator
type-specifier
declarator
opt:
constant-expression
constant-expression
指定域的宽度(以位为单位)。 declarator
的 type-specifier
必须为 unsigned int
、signed int
或 int
,而且 constant-expression
必须为非负整数值。 如果值为零,则声明没有任何 declarator
。 不允许位域的数组、指向位域的指针和返回位域的函数。 可选的 declarator
命名位域。 位域只能声明为结构的一部分。 address-of 运算符 (&
) 不能应用于位域组件。
未命名位域不可引用,且其内容在运行时是不可预测的。 它们可以出于对齐目的用作“虚拟”字段。 宽度指定为 0 的未命名位域确保在 struct-declaration-list 中跟在其后的成员的存储在 int
边界开始。
位字段中的位数必须小于或等于基础类型的大小。 例如,以下两个语句均不合法:
short a:17; /* Illegal! */
int long y:33; /* Illegal! */
以下示例定义了一个名为 screen
的二维结构数组。
struct
{
unsigned short icon : 8;
unsigned short color : 4;
unsigned short underline : 1;
unsigned short blink : 1;
} screen[25][80];
该数组包含 2,000 个元素。 每个元素都是包含以下四个位域成员的单个结构:icon
、color
、underline
和 blink
。 每个结构的大小是 2 个字节。
位域与整数类型具有相同的语义。 位域在表达式中的使用方式与同样基类型使用变量的方式完全相同。 位域中有多少位并不重要。
Microsoft 专用
定义为 int
的位域被视为 signed
。 ANSI C 标准的 Microsoft 扩展允许对位域使用 char
和 long
类型(signed
和 unsigned
)。 带基类型 long
、short
或 char
(signed
或 unsigned
)的未命名位域强制与适合基类型的边界对齐。
在整数中按照从最高有效位到最低有效位的顺序来分配位域。 在以下代码中
struct mybitfields
{
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
} test;
int main( void )
{
test.a = 2;
test.b = 31;
test.c = 0;
return 0;
}
test
的位将按如下所示排列:
00000001 11110010
cccccccb bbbbaaaa
由于 8086 系列处理器将整数值的低字节存储在高字节之前,因此整数 0x01F2
将按 0xF2
后跟 0x01
的形式存储在物理内存中。
ISO C99 标准允许实现选择位域是否可以跨两个存储实例。 请考虑这种结构,其中存储了共计 64 位的位域:
struct
{
unsigned int first : 9;
unsigned int second : 7;
unsigned int may_straddle : 30;
unsigned int last : 18;
} tricky_bits;
标准 C 实现可以将这些位域打包成两个 32 位整数。 它可以将 tricky_bits.may_straddle
作为 16 位存储在一个 32 位整数中,作为 14 位存储在下一个 32 整数中。 Windows ABI 约定将位域打包成单个存储整数,不跨存储单元。 Microsoft 编译器将存储上述示例中的每个位域,使它完全适应单个 32 位整数。 在这种情况下,first
和 second
存储在一个整数中,may_straddle
存储在另一个整数中,last
存储在第三个整数中。 如果是一个 tricky_bits
实例,sizeof
运算符则返回 12
。 有关详细信息,请参阅结构成员的填充和对齐。
结束 Microsoft 专用
请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈