巧用Bit Fields 精减结构体存储空间的方法
2009-07-14 15:02
246 查看
Bit Fields这个词我不知道怎么翻译,暂时叫它“比特域”吧,我们可以用它来声明一个占用最小空间的结构体,用来声明的变量类型可以是BYTE,WORD,DWORD等。例如,我们现在要一个存储日期的最小长度的结构体date_struct。我们可以这样声明:
struct date_struct {
WORD day : 5, // 1 to 31
month : 4, // 1 to 12
year : 14; // 0 to 9999
} date;
在这个结构体中,变量day(日)占用5个比特位,month(月)占用4个比特位, year(年)占用14个比特位。所以我们可以存储这个结构体在大小为23bit(3 BYTEs)的空间里(实际上有4 BYTE),而第24个比特位到第32个比特位的内容将忽略掉。如果我们将各个变量用integer来声明,那这个结构体将占用12 BYTEs。
![](http://blog.csdn.net/userfiles/2(5).jpg)
现在我们来看一下这一声明是如何进行的。
首选来看这个比特域结构体中用到的数据类型。在这个例子里面我用到的WORD,1 WORD等于2个BYTE,1 BYTE等于8个比特(bit)。在编译的时候,编译器将为它分配一个WORD的空间,当然了,我们结构体里所要求的空间超过1个WORD,编译器会为它再分配一个WORD,所以当我们结构体里需要多少WORD时,编译器将为它分配多少WORD。在这里我们需要问的是,为什么,我们在结构体里的数据类型要用WORD,而不用BYTE或者是integer。这就要视实际情况而定:
(1)、为什么在这个例子里不用BYTE?
因为我们的结构体里的year变里的分配需要14 bit才能满足要求,而在VC 6.0编译器中要求,为每个变量分配的比特数不能超过声明它的数据类型所要求的比特数。所以BYTE只有8 bit,不能满足要求,而WORD有16 bit,恰好可以用。如果在本例中一意独行用BYTE的话,就会出现编译错误:error XXXX: 'year' : type of bit field too small for number of bits
(2)、为什么在这个例子里没有用其它类型?
结构体的比特域中使用的数据类型最好是该数据类型所要求的比特数刚好大于比特域变量中所要求的最大比特数。这就是问题的答案,例如,在本例中,如果把变量month所要求的比特数由4改为14。
![](http://blog.csdn.net/userfiles/1(6).jpg)
此时各变量所要求的比特总和为:5+14+14=33(bit)。当数据变量类型为WORD时,编译器将为它分配3个WORD(3*16(bit)=48(bit)),即6个BYTE(6*8(bit)=48(bit))。当数据变量类型为int时(int类型要求分配空间为4 BYTE),编译器将为它分配2个DWORD,即4个WORD(4*16(bit)=64(bit)),也就是8个BYTE (8*8(bit)=64(bit))。 由此可见对数据类型的声明得小心。
接着我们来如看变量域的声明。我们的变量名 (day, month, and year)后面跟着冒号,冒号后面跟着的数字为所要求的比特个数。各个变量都有逗号隔开,在声明的最后跟上分号。虽然我们不能获得比特域变量的地址,但我们可以通过结构体变量名来对它们进行操作。
如下是一段应用的小例子:
#include <windows.h>
#include <stdio.h>
struct date_struct {
WORD day:5, //1 to 31
month:4, //1 to 12
year:14; //0 to 9999
}date;
void main()
{
struct date_struct *dateptr;
date.day=12;
dateptr=&date;
dateptr->year=1852;
dateptr->month=6;
printf("%d:%d:%d/n",date.day,date.month,date.year);
}
通过上面的论述,我们可以发现,在本例中用比特域声明进行数据存储所需要的空间(4 BYTE)是单纯使用int类型进行数据存储空间(12 BYTE)的三分之一。有什么想法呢?
struct date_struct {
WORD day : 5, // 1 to 31
month : 4, // 1 to 12
year : 14; // 0 to 9999
} date;
在这个结构体中,变量day(日)占用5个比特位,month(月)占用4个比特位, year(年)占用14个比特位。所以我们可以存储这个结构体在大小为23bit(3 BYTEs)的空间里(实际上有4 BYTE),而第24个比特位到第32个比特位的内容将忽略掉。如果我们将各个变量用integer来声明,那这个结构体将占用12 BYTEs。
![](http://blog.csdn.net/userfiles/2(5).jpg)
现在我们来看一下这一声明是如何进行的。
首选来看这个比特域结构体中用到的数据类型。在这个例子里面我用到的WORD,1 WORD等于2个BYTE,1 BYTE等于8个比特(bit)。在编译的时候,编译器将为它分配一个WORD的空间,当然了,我们结构体里所要求的空间超过1个WORD,编译器会为它再分配一个WORD,所以当我们结构体里需要多少WORD时,编译器将为它分配多少WORD。在这里我们需要问的是,为什么,我们在结构体里的数据类型要用WORD,而不用BYTE或者是integer。这就要视实际情况而定:
(1)、为什么在这个例子里不用BYTE?
因为我们的结构体里的year变里的分配需要14 bit才能满足要求,而在VC 6.0编译器中要求,为每个变量分配的比特数不能超过声明它的数据类型所要求的比特数。所以BYTE只有8 bit,不能满足要求,而WORD有16 bit,恰好可以用。如果在本例中一意独行用BYTE的话,就会出现编译错误:error XXXX: 'year' : type of bit field too small for number of bits
(2)、为什么在这个例子里没有用其它类型?
结构体的比特域中使用的数据类型最好是该数据类型所要求的比特数刚好大于比特域变量中所要求的最大比特数。这就是问题的答案,例如,在本例中,如果把变量month所要求的比特数由4改为14。
![](http://blog.csdn.net/userfiles/1(6).jpg)
此时各变量所要求的比特总和为:5+14+14=33(bit)。当数据变量类型为WORD时,编译器将为它分配3个WORD(3*16(bit)=48(bit)),即6个BYTE(6*8(bit)=48(bit))。当数据变量类型为int时(int类型要求分配空间为4 BYTE),编译器将为它分配2个DWORD,即4个WORD(4*16(bit)=64(bit)),也就是8个BYTE (8*8(bit)=64(bit))。 由此可见对数据类型的声明得小心。
接着我们来如看变量域的声明。我们的变量名 (day, month, and year)后面跟着冒号,冒号后面跟着的数字为所要求的比特个数。各个变量都有逗号隔开,在声明的最后跟上分号。虽然我们不能获得比特域变量的地址,但我们可以通过结构体变量名来对它们进行操作。
如下是一段应用的小例子:
#include <windows.h>
#include <stdio.h>
struct date_struct {
WORD day:5, //1 to 31
month:4, //1 to 12
year:14; //0 to 9999
}date;
void main()
{
struct date_struct *dateptr;
date.day=12;
dateptr=&date;
dateptr->year=1852;
dateptr->month=6;
printf("%d:%d:%d/n",date.day,date.month,date.year);
}
通过上面的论述,我们可以发现,在本例中用比特域声明进行数据存储所需要的空间(4 BYTE)是单纯使用int类型进行数据存储空间(12 BYTE)的三分之一。有什么想法呢?
相关文章推荐
- 为结构体分配额外存储空间的方法
- 安卓手机安装软件提示存储空间不足的解决方法
- Android 最新获取手机内置存储大小,SD卡存储空间大小方法
- Android手机总是提示:存储空间不足,解决方法
- 安卓手机安装软件提示存储空间不足的解决方法
- mysql存储IP地址省空间的方法
- 【C语言】结构体存储与空间分配
- Android 获取SD路径,存储空间大小的方法
- mysql存储IP地址省空间的方法
- 【转】C语言中结构体的位域(bit-fields)
- C语言中结构体的位域(bit-fields)
- Android 获取SD路径,存储空间大小的方法
- 共享一文件夹提示"服务器存储空间不足,无法处理此命令"的问题解决方法
- iOS _查询所剩内存和所剩存储空间的方法
- C++:编写一个程序,用动态分布分配空间的方法计算Fibonacci数列的前二十项并存储到动态分布的空间中
- Win7存储空间不足怎么办?Win7存储空间不足的两种解决方法
- 管理空闲存储空间的方法-位示图法
- [转]扩展Windows Mobile模拟器存储空间的方法
- 关于检测手机内部存储的方法(以内置存储空间几乎为0M时添加联系人为例)