美丽的小岛 发表于 2013-1-26 12:28:34

C的位结构体

 学习C有些时间了,知道有结构体,但是偶然知道它还有位结构体,查了些资料,也做了一个实验。
1.概念性描述:
位结构是一种特殊的结构, 在需按位访问一个字节或字的多个位时, 位结构比按位运算符更加方便。
位结构定义的一般形式为:
struct  位结构名{
数据类型 [变量名]: 整型常数; //成员称为“位域”或者“位段”
数据类型 [变量名]: 整型常数;
} 位结构变量;
其中: 数据类型必须是整型(int/char/short)。 整型常数的范围是数据类型的长度, 如定义为short,则范围是1~16。
变量名是选择项, 可以不命名, 这样规定是为了排列需要。
例如: 下面定义了一个位结构。
struct webpage{
unsigned char incon: 8; /*incon占用低字节的0~7共8位*/
unsigned char txcolor: 4;/*txcolor占用高字节的0~3位共4位*/
unsigned char bgcolor: 3;/*bgcolor占用高字节的4~6位共3位*/
unsigned char blink: 1; /*blink占用高字节的第7位*/
}ch;
printf("%d\n",sizeof(struct webpage));输出:2。
位结构成员的访问与结构成员的访问相同。
例如: 访问上例位结构中的bgcolor成员可写成:
ch.bgcolor
注意:
1. 一个位域必须存储在定义它的一个数据类型内部,不能跨跨该数据类型。如char定义的位域所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。
2.由于位域不允许越过定义它的数据类型,因此位域的长度不能大于定义它的数据类型的长度。
3. 位结构总长度(位数), 是各个位成员定义的位数之和再向最大结构成员对齐。
4. 位结构成员可以与其它结构成员一起使用。
2.写下面的代码
#include "stdio.h"int main(){   union    {      struct student      {            unsigned char s1:3;            unsigned char s2:3;            unsigned short s3:3;      }x;      unsigned short s;      unsigned int i ;    }v;v.i=0;v.x.s1=1;v.x.s2 =8;v.x.s3=1;printf("v.i = %d\n",v.i);printf("v.s = %d\n",v.s);printf("v.x.s1 = %d\n",v.x.s1) ;printf("v.x.s2 = %d\n",v.x.s2) ;printf("v.x.s3 = %d\n",v.x.s3) ;v.s = 0x10A ;printf("v.i = %d\n",v.i);printf("v.s = %d\n",v.s);printf("v.x.s1 = %d\n",v.x.s1) ;printf("v.x.s2 = %d\n",v.x.s2) ;printf("v.x.s3 = %d\n",v.x.s3) ;printf("size:%d\n",sizeof(v));return 0 ;}3.得出下面的结果 
http://dl.iteye.com/upload/attachment/0072/3644/4c0fc1c6-6122-3255-aeb2-7d9f9c9c7d20.bmp
4.作以下的分析
上面的结构中都是3个3个的,用九位来分析,v.i=0;语句形成图1的情况,除了这9位还有23位都是0 :
图1:
+----+----+----+----+----+----+----+----+----+
 |        s3        |         s2        |        s1         | 
+----+----+----+----+----+----+----+----+----+
 |  9  |  8 |  7  |  6  |  5  |  4  |  3  |  2  |  1  | 
+----+----+----+----+----+----+----+----+----+
 |  0  |  0 |  0  |  0  |  0  |  0  |  0  |  0  |  0  | 
+----+----+----+----+----+----+----+----+----+
经过v.x.s1=1,v.x.s2 =8;v.x.s3=1;这三个赋值后,就变成了图2的的那样了。图2了,打印出来也看到了。果真是这样的。
+----+----+----+----+----+----+----+----+----+
 |        s3        |         s2        |        s1         | 
+----+----+----+----+----+----+----+----+----+
 |  9  |  8 |  7  |  6  |  5  |  4  |  3  |  2  |  1  | 
+----+----+----+----+----+----+----+----+----+
 |  0  |  0 |  1  |  0  |  0  |  0  |  0  |  0  |  1  | 
+----+----+----+----+----+----+----+----+----+
对于这个语句v.s = 0x10A ;的赋值,想看看联合体中的元素是不是共用一块内存,看到的果然也在意料之内。0x10A的二进制就是下面的9位所显示的。打印出来也是意料的那样。
图3:
+----+----+----+----+----+----+----+----+----+
 |        s3        |         s2        |        s1         | 
+----+----+----+----+----+----+----+----+----+
 |  9  |  8 |  7  |  6  |  5  |  4  |  3  |  2  |  1  | 
+----+----+----+----+----+----+----+----+----+
 |  1  |  0 |  0  |  0  |  0  |  1  |  0  |  1  |  0  | 
+----+----+----+----+----+----+----+----+----+
最后还打印出来整个字联合体大小为4,这个是int型决定的字节数。
 
5.参考:
http://hi.baidu.com/wliangde/item/e00d0b37cf3c57dd6c15e9ee
页: [1]
查看完整版本: C的位结构体