Bit field
来源:互联网 发布:javascript特效代码 编辑:程序博客网 时间:2024/05/17 00:05
c 语言中的bit field 是一种节省内存的方式, 用于struct 或者 union 的成员变量的声明。基本的语法是:
struct BF { ... type_specifier [declarator] : constant_expression; ...};
采用这样一种方式的好处是,我们可以明确地指定某一个成员变量在内存中占用的空间(constant_expression bits). 比如:
struct BitArray { unsigned a : 1; unsigned b : 1;};// sizeof(BitArray) == 4struct BitArray2{ unsigned a; unsigned b;};// sizeof(BitArray2) == 8
上面的例子可以看出,使用了Bit field, 我们可以将相邻的变量a
和 b
紧凑的排列到一个unsigned
中。 而如果不适用Bit field, 很明显编译器将会单独为a
和 b
创建一个 unsigned
成员变量。
但是在使用bit field的时候,我们发现有很多限制或者注意点,这里罗列出大部分可能会碰到的问题。
- 底层数据类型
bit field 本身不是C/C++的基本类型,需要依附于底层数据在内存中的表示。一般多个bit fields 会共享一个底层数据类型所占用的内存空间。 底层类型只能是整形(char, short, int, long, long long 和 unsigned 变种) 或者枚举类型(enum ) :
enum E { E1, E2, E3, E4, E5, E6 = 200 };struct SMixture { char a : 1, b : 1 ; //ok E e1 : 2, e2 : 2; //ok float f : 3 ; //compiler error};
- 如果底层类型大小不足以容纳所有的 bit fields, 则在内存中开辟新的底层数据类型以容纳更多的域,但是多余的域不会横跨相邻的底层数据空间,而是开辟新的空间开始放置多余的Bit fields.
struct SMixture { char a : 1; //start of first char char b : 3; //continue in the first char char c : 5; //start of second char char d : 4; //start of third char};// sizeof(SMixture) == 3;
- 匿名域(unnamed bit field)起padding的作用。 如果域的大小为0,则必须匿名(unnamed ).
struct SMixture { char c : 1; char d : 0; //compiler error char : 0; //okay};
width 为0的域是特殊域,表示该0-width bit field的下一个成员的地址必须以该0-width bit field 的类型的对齐方式对齐。
struct SMixture { char c : 1; //start of char int : 0; short d : 1; //start of short after alignment at type int boundary};//sizeof(SMixture) == 6;struct SMixture2 { char c : 1; //start of char int : 0; short d; //start of short after alignment at type int boundary};//sizeof(SMixture2) == 6
- 不能通过地址操作符(&)获取bit field的地址,因此bit field不能通过指针访问, 也不能通过引用访问。
int main(){ SMixture s; short* ps = &s.d; //compiler error short& rs = s.d; //compiler error return 0;}
- Bit field 不能是 static 成员。
struct SMixture { static char c : 1; //compiler error};
- 使用bit field 的初衷是为了节省内存的消耗,但是最终的结果可能事与愿违。虽然bit field一定会减少类型的数据空间, 但是为了进行比特位操作,编译器不得不在生成的代码中加入额外的控制代码。因此最终的代码有可能比不使用bit field的情形还要大。另外一方面,直接访问整型数据类型一定会比访问bit fields要快。因此,在代码中使用bit field的情形可能相当有限。比如, 在这篇stackoverflow的文章中提到跨平台或者硬件的二进制文件的兼容问题,此时可能需要将某些成员变量强制对齐到某个位置:
/* from xnu/bsd/netinet/bootp.h *//* * Bootstrap Protocol (BOOTP). RFC 951. *//* * HISTORY * * 14 May 1992 ? at NeXT * Added correct padding to struct nextvend. This is * needed for the i386 due to alignment differences wrt * the m68k. Also adjusted the size of the array fields * because the NeXT vendor area was overflowing the bootp * packet. *//* . . . */struct nextvend { u_char nv_magic[4]; /* Magic number for vendor specificity */ u_char nv_version; /* NeXT protocol version */ /* * Round the beginning * of the union to a 16 * bit boundary due to * struct/union alignment * on the m68k. */ unsigned short :0; union { u_char NV0[58]; struct { u_char NV1_opcode; /* opcode - Version 1 */ u_char NV1_xid; /* transcation id */ u_char NV1_text[NVMAXTEXT]; /* text */ u_char NV1_null; /* null terminator */ } NV1; } nv_U;};
0 0
- Bit field
- Bit field
- Bit field of struct
- 位域(Bit Field)
- c++ bit field
- c bit field
- typedef union bit-field
- 位段(bit-field)
- (C)位字段(bit-field)
- 转贴:关于C结构体bit field
- struct bit-field与little-endian
- bit field(位段,位域)
- 在c++中的bit field位域
- error: negative width in bit-field ‘<anonymous>’
- C/C++ 中的位域 bit field
- c结构之位域bit field
- 位域(bit-field):一种压缩空间的成员
- 如何使用EnumSet实现基于bit field的enum set?
- 21. Merge Two Sorted Lists
- MySQL 数据库设计初步规范
- 关于错误样式遮挡点击事件问题
- 基于FPGA的图像处理--基本概念导图
- kidd风的IOS日志之GCD详解
- Bit field
- 消息队列MQ】各类MQ比较
- 腾讯手机助手
- java 消息机制 ActiveMQ入门实例
- 我拿什么来爱你
- Spring+Log4j+ActiveMQ实现远程记录日志
- 五种布局
- JMS activeMQ
- css3属性 滤镜详解