在写通讯协议的时候用到有关位结构体和union的相关内容,整理一部分东西:
首先摘一段《C语言编程宝典》上关于位结构体的说明:
/*************以下文字摘自《C语言编程宝典》********************/
位结构是一种特殊的结构, 在需按位访问一个字节或字的多个位时, 位结构
比按位运算符更加方便。
位结构定义的一般形式为:
struct位结构名{
数据类型 变量名: 整型常数;
数据类型 变量名: 整型常数;
} 位结构变量;
其中: 数据类型必须是int(unsigned或signed)。 整型常数必须是非负的整
数, 范围是0~15, 表示二进制位的个数, 即表示有多少位。
变量名是选择项, 可以不命名, 这样规定是为了排列需要。
例如: 下面定义了一个位结构。
struct{
unsigned incon: 8; /*incon占用低字节的0~7共8位*/
unsigned txcolor: 4;/*txcolor占用高字节的0~3位共4位*/
unsigned bgcolor: 3;/*bgcolor占用高字节的4~6位共3位*/
unsigned blink: 1; /*blink占用高字节的第7位*/
}ch;
位结构成员的访问与结构成员的访问相同。
例如: 访问上例位结构中的bgcolor成员可写成:
ch.bgcolor
注意:
1. 位结构中的成员可以定义为unsigned, 也可定义为signed, 但当成员长
度为1时, 会被认为是unsigned类型。因为单个位不可能具有符号。
2. 位结构中的成员不能使用数组和指针, 但位结构变量可以是数组和指针,
如果是指针, 其成员访问方式同结构指针。
3. 位结构总长度(位数), 是各个位成员定义的位数之和, 可以超过两个字
节。
4. 位结构成员可以与其它结构成员一起使用。
例如:
struct info{
char name[8];
int age;
struct addr address;
float pay;
unsigned state: 1;
unsigned pay: 1;
}workers;'
上例的结构定义了关于一个工从的信息。其中有两个位结构成员, 每个位结
构成员只有一位, 因此只占一个字节但保存了两个信息, 该字节中第一位表示工
人的状态, 第二位表示工资是否已发放。由此可见使用位结构可以节省存贮空间。
/******************************************************/
补充说明一点,如果要定义超过两个字节的位结构体,需要注意,按字节填充!!!即:
比如定义一个4字节的位结构体,应该这样定义:
struct bitstruct {
unsigned a: 8;
unsigned b: 1;
unsigned c: 2;
unsigned d: 5:
signed int e:16;
}data;
而不要这样定义:
struct bitstruct {
unsigned a: 8;
unsigned b: 1;
unsigned c: 2;
signed int e:16;
unsigned d: 5:
}data;
因为C语言在填充的时候,最小的填充方式是按字节填充的,所以要以字节为单位。
关于和union的结合
union因为其可以互换的数据结构,在数据通讯协议中常常会使用到,一般我们这样定义数据通信协议结构包
struct rawstruct{
int a;
long b;
};//2+4 = 6 byte
union rawstruct{
struct rawstruct structdata;
unsigned char unionchar[6];
};
这样对数据的打包和解包就能方便实现。
union和位结构体的结合:
如上面定义的位结构体,甚至可以定义下面的union结构
struct bitstruct {
unsigned a: 8;
unsigned b: 1;
unsigned c: 2;
unsigned d: 5:
signed int e:16;
}data;
union rawstruct{
struct bitstruct datas[8];
signed long unionchar[8];
};
评论