一、引言
有些信息在存储时,并不需要占用完整的字节,例如开关变量,只需要占用一位。这时,我们就可以采用位域操作,将一个字节分成不同的区域,并说明每个区域的位数,来节省内存。
二、应用
2.1 位域的定义
struct 位于结构名
{
type member_name : width;
}
- 代码实现:
#include <stdio.h> #include <string.h> struct test1 { unsigned int i; unsigned int j; }; struct test2 { unsigned int i : 1; unsigned int j : 1; }; int main() { struct test1 t1; struct test2 t2; t2.i = 1; t2.j = 2; printf("i的大小:%d\n",t2.i); // 此处会有警告,因为j的内存超出了位域定义的大小 // 输出结果为0 printf("j的大小:%d\n",t2.j); printf("t1的大小:%d\n",sizeof(t1)); printf("t2的大小:%d\n",sizeof(t2)); return 0; }
- 运行结果:
test1.c: In function 'main': test1.c:21:12: warning: large integer implicitly truncated to unsigned type [-Woverflow] t2.j = 2; ^ i的大小:1 j的大小:0 t1的大小:8 t2的大小:4
2.2 结构体的位域大小
- 代码实现:
#include<stdio.h> /* 在定义位域的时候,当一个单元的位置不够存放另一 位域的时候,会从下一单元存放该位域 单元:一般指四个字节,即一个整型变量的长度 */ // 结构体大小:4字节 struct test1 { unsigned i : 31; unsigned j : 1; }; // 结构体33个比特,超过一个单元(32比特),j // 被存放到下一个单元,故占用8个字节 struct test2 { unsigned i : 31; unsigned j : 2; }; // 加入空域,内存大小为8个字节,j存放在下一个单元 struct test3 { unsigned i : 31; unsigned : 1; unsigned j : 1; }; int main(){ struct test1 t1; struct test2 t2; struct test3 t3, *p_t3; p_t3 = &t3; // 注意是使用->而不是 . ,否则会报错 // 因为p_t3为指针,如果不是指针,则用 . 进行赋值 p_t3->i = 8; p_t3->j = 1; printf("t3.i:%d\n",t3.i); printf("t3.j:%d\n",p_t3->j); printf("t1的大小:%d\n",sizeof(t1)); printf("t2的大小:%d\n",sizeof(t2)); printf("t3的大小:%d\n",sizeof(t3)); }
- 运行结果:
t3.i:8 t3.j:1 t1的大小:4 t2的大小:8 t3的大小:8