?
This document uses PHP Chinese website manual Release
以位為單位聲明一個(gè)明確寬度的成員。相鄰的位字段成員可以打包以共享和跨越單個(gè)字節(jié)。
位字段聲明是使用以下聲明的結(jié)構(gòu)或聯(lián)合成員聲明:
identifier(optional) : width |
---|
標(biāo)識(shí)符 | - | 正在聲明的位字段的名稱。該名稱是可選的:無名稱位域引入了指定的填充位數(shù) |
---|---|---|
寬度 | - | 一個(gè)整數(shù)常量表達(dá)式,其值大于或等于零且小于或等于基礎(chǔ)類型中的位數(shù)。當(dāng)大于零時(shí),這是該位字段將占用的位數(shù)。值零只能用于無名的位域,具有特殊含義:它指定類定義中的下一個(gè)位域?qū)姆峙鋯卧倪吔玳_始。 |
位域只能有四種類型之一(可能是 const 或 volatile 限定的):
unsigned int
,對(duì)于無符號(hào)位域(unsigned int b:3;
有范圍0..7
)
signed int
,對(duì)于有符號(hào)位域(signed int b:3;
有范圍-4..3
)
int
,對(duì)于具有實(shí)現(xiàn)定義的簽名的位字段(請(qǐng)注意,這與int
其他地方的關(guān)鍵字的含義不同,它表示“signed int”)。例如,int b:3;
可能有值的范圍0..7
或-4..3
。
_Bool
,用于單位位域(bool x:1;
具有范圍0..1
和隱式轉(zhuǎn)換,它遵循布爾轉(zhuǎn)換規(guī)則。
額外的實(shí)現(xiàn)定義類型可能是可以接受的。它也是實(shí)現(xiàn)定義是否一個(gè)位域可能有原子類型。(自 C11開始)位域(寬度)中的位數(shù)將限制設(shè)置為可容納的值范圍:
#include <stdio.h>struct S { // three-bit unsigned field, // allowed values are 0...7 unsigned int b : 3;};int main(void){ struct S s = {7}; ++s.b; // unsigned overflow printf("%d\n", s.b); // output: 0}
允許多個(gè)相鄰位字段(通常是)打包在一起:
#include <stdio.h>struct S { // will usually occupy 4 bytes: // 5 bits: value of b1 // 11 bits: unused // 6 bits: value of b2 // 2 bits: value of b3 // 8 bits: unused unsigned b1 : 5, : 11, b2 : 6, b3 : 2;};int main(void){ printf("%zu\n",sizeof(struct S)); // usually prints 4}
寬度為零的特殊未命名位字段分隔填充:它指定下一個(gè)位字段從下一個(gè)分配單元的開始處開始:
#include <stdio.h>struct S { // will usually occupy 8 bytes: // 5 bits: value of b1 // 27 bits: unused // 6 bits: value of b2 // 15 bits: value of b3 // 11 bits: unused unsigned b1 : 5; unsigned :0; // start a new unsigned int unsigned b2 : 6; unsigned b3 : 15;};int main(void){ printf("%zu\n", sizeof(struct S)); // usually prints 8}
由于位字段不一定在字節(jié)的開始處開始,所以不能采用位字段的地址。指向位字段是不可能的。位字段不能與 sizeof 和 alignas 一起使用(自 C11開始)。
位字段的以下屬性未定義:
調(diào)用offsetof
位域的效果
位字段的以下屬性未指定:
保存位域的分配單元的對(duì)齊
位域的以下屬性是實(shí)現(xiàn)定義的:
類型的位字段是否int
被視為有符號(hào)或無符號(hào)
是否允許 int,signed int,unsigned int和_Bool 以外的類型
原子類型是否被允許
位域是否可以跨越分配單位邊界
分配單元中的位字段的順序(在某些平臺(tái)上,位字段從左到右打包,其他從右到左)
即使對(duì)象表示中的位數(shù)_Bool
至少CHAR_BIT
為_Bool
1 ,類型的位字段的寬度也不能大于1。
在 C ++編程語言中,位域的寬度可以超過基礎(chǔ)類型的寬度。
C11 standard (ISO/IEC 9899:2011):
6.7.2.1 Structure and union specifiers
C99 standard (ISO/IEC 9899:1999):
6.7.2.1 Structure and union specifiers
C89/C90 standard (ISO/IEC 9899:1990):
3.5.2.1 Structure and union specifiers