结构体中的冒号表示位域。
由于某些信息的存储表示只需要几个bit位就可以表示而不需要一个完整的字节,
同时也是为了节省存储空间。
struct 位域结构名 {
类型说明符 位域名:位域长度
}
例如:
struct bit_struct {
int bit1:3;
int bit2:5;
int bit3:7;
} data;
其中bit_struct表示位域结构体,bit1、bit2、bit3表示对应的位域。
整个位域结构体占用2个字节:
bit1占3位,bit2占5位,bit1和bit2共用一个字节,bit3占7位,独占一个字节。
说明:
1、位域必须存储在同一个类型中,不能跨类型,位域的长度不会超过所定义类型的长度。
若一个定义类型单元所剩空间无法存放下一个域,则下一个域应该从下一单元开始存放。
例如:int类型32位,用掉25位还剩7位,接着要存储一个8位的位域元素,
那么这个元素就只能从下一个int类型的单元开始,
而不会在前面一个int类型中占7位,后面的int类型中占1位。
2、如果位域的位域长度为0,表示空域,下一个域应从下一个字节单元开始存放。
3、无名的位域来填充和调整位置,不能被使用。
4、位域本质是一种结构体类型,不同的是其成员按二进制bit位来分配。
``````
#include <stdio.h>
#define SYS_OK 0
#define SYS_FAILED 1
typedef int SYS_TYPE;
SYS_TYPE main() {
struct bit_st {
int a:3; //第一个字节的0~2位
int :0; //空域,下一个位域b将会从下一个字节开始,位3~7为全0
int b:2; //下一个字节也就是第二个字节的0~1位
int c:5; //第二个字节紧接b之后的2~6位
int d:2; //第二个字节紧接c之后的7~8位
int :2; //d域后的两个位9~10不能使用
int e:3; //第二个字节的11~12位
}data, *pData;
// a的范围:-4 ~ 3
// b的范围:-2 ~ 1
// c的范围:-16 ~ 15
// d的范围:-2 ~ 1
// e的范围:-4 ~ 3
data.a = 1; // 1
data.b = 2; // 上限+1 = 下限 -2
data.c = 3; // 3
data.d = 2; // 上限+1 = 下限 -2
data.e = 4; // 上限+1 = 下限 4
printf("a = %d, b = %d, c = %d, d = %d, e = %d\r\n",
data.a, data.b, data.c, data.d, data.e);
pData = &data;
pData->a = 3; // 3
pData->b &= 1; // 本来是 -2(0b10),& 1(0b01) 之后是 0b00 = 0
pData->c |= 5; // 本来是 3(0b00011),| 5(0b00101) 之后是 0b00111 = 7
pData->d ^= 1; // 本来是 -2(0b10),^ 1(0b01) 之后是 0b11 -1
pData->e = 5; // 0b101 = -3
printf("a = %d, b = %d, c = %d, d = %d, e = %d\r\n",
pData->a, pData->b, pData->c, pData->d, pData->e);
printf("%d %d\n", sizeof(struct bit_st), sizeof(int));
return SYS_OK;
}
#./main
a = 1, b = -2, c = 3, d = -2, e = -4
a = 3, b = 0, c = 7, d = -1, e = -3
8 4