位域
有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。
注:其中位域的值不能超过该数据类型的最大二进制位个数,例char 一字节(8位),意味着位域的值<=8
举例说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <stdio.h> struct Node { unsigned char a:3; char b:2; unsigned char c:5; char d:4; };
int main() { struct Node test = {0}; test.a = 7; test.b = 6; test.c = 17; test.d = 8;
printf("a = %d\n", test.a); printf("b = %d\n", test.b); printf("c = %d\n", test.c); printf("d = %d\n", test.d); printf("size = %d\n", sizeof(struct Node)); return 0; }
|
画个图理解下:

结果:

主要用途
主要用来制定协议
- 例如熟知的IP协议数据报格式

- 编写个日期的数据报
1 2 3 4 5 6
| struct Data { unsigned int day:5 unsigned int month:4; unsigned int year:23; };
|
结构图如下:

- 字节大小

注意:在使用位域的结构体后,不能使用结构体中的元素类型的指针来访问结构体元素的地址;
看清区别,理解本质
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| struct Node { unsigned char a:3; char b:2; unsigned char c:5; char d:4; };
struct Node_Int { unsigned int a:3; int b:2; unsigned int c:5; int d:4; };
|
- 所占大小


匿名位域
1 2 3 4 5 6
| struct Node { unsigned char a:3; char b:0; unsigned char c:5; };
|

1 2 3 4 5 6
| struct Node { unsigned char a:3; char b:2; unsigned char c:3; };
|

只要是结构体,就要遵循内存对齐
不管结构体中是否使用位域,都要进行内存对齐;
1 2 3 4 5
| struct Node { unsigned char a:3; int b:6; };
|
