经过个人查阅相关的资料和理解,现对C语言的位域做一个总结,对于位域的定义我在这里没有多说,我这里主要是对位域有歧义的地方进行系统的总结.我个人觉得总结的比较完整,如有不够完整或有异义的地方大家可以留言指点.
1.位域又叫位段(位字段),是一种特殊的结构成员或联合成员(即只能用在结构或联合中),用于指定该成员在内存存储时所占用的位数,从而可以在机内更紧凑地表示数据。
2.位域的使用主要出现在如下两种情况:
(1)当机器可用内存空间较少而使用位域可以大量节省内存时。如,当把结构作为大数组的元素时。
(2)当需要把一结构或联合映射成某预定的组织结构时。例如,当需要访问字节内的特定位时。
3.当要把某个成员说明成位域时,其类型只能是int,unsigned int与signed int三者之一(说明:int类型通常代表特定机器中整数的自然长度。short类型通常为16位,long类型通常为32位,int类型可以为16位或32位.各编译器可以根据硬件特性自主选择合适的类型长度.见The C Programming Language中文 P32)。
4.带位域的结构在内存中各个位域的存储方式取决于具体的编译程序;它们既可以从左到右,也可以从右到左存储。
5.在一包含位域说明的强构或联合区分符中也可以同时说明普通成员,例如:
struct st1
{
unsigned a:7;
unsigned b:4;
unsigned c:5;
int i; //i是普通成员,这会被存放在下一个字,即字对齐
};
6.int值不能跨字存放,同样位域也最好不要跨字存放(意思说是说:各位域的分配位数加起来要在16位或32位以内,如果编译器分配int为16位,则加起来要在16位以内,如果加起来大于16位,则最好空出剩余的位域,从下一个字开始分配位域).
7.特殊宽度0或者说长度为0的无名位域有着特殊的用途.它用于指示将其前后的两个位域或成员分开放在两个字中, 即将位于该无名位域后的下一个位域从下一个字开始存放.
8.位域备注:
关于位域还需要提醒读者注意如下几点:
其一,位域的长度不能大于int对象所占用的字位数.例如,若int对象占用16位,则如下位域说明是错误的:
unsigned int x:17;
其二,由于位域的实现会因编译程序的不同而不同,在此使用位域会影响程序的可移植性,在不是非要使用位域不可时最好不要使用位域.
其三,尽管使用位域可以节省内存空间,但却增加了处理时间,在为当访问各个位域成员时需要把位域从它所在的字中分解出来或反过来把一值压缩存到位域所在的字位中.
其四,位域的位置不能访问,因些不能对位域使用地址运算符号&(而对非位域成员则可以使用该运算符).从而,即不能使用指向位域的旨针也不能使用位域的数组(因为数组实际上就是一种特殊的指针).另外,位域也不能作为函数返回的结果.
最后还要强调一遍:位域又叫位段(位字段),是一种特殊的结构成员或联合成员(即只能用在结构或联合中).
说明:以上大多数文字摘自《ANSI C标准详解》及《The C Programming Language中文第二新版》.在此对以上两本参考书的团体表示感谢.
加速度 March.6.2010