数据在存储的时候,并不需要占用一个完整的单元,只需要占用一个或者几个二进制位,限定数据的位数,节约内存资源
简单来说就是,比如一个int,一般来说占用四个字节,那么四个字节就是32个位,但是我们实际当中用到的数据用不了那么多位,比如我们要存储月份,那么月份是不是就是1-12呢,那么我们这个时候就可以把这个int类型设计成四个位,那么它能存储最大的数据就是1111,对吗,也就是0-15的范围,存储2^4个数据,那么这个范围就是我们想要的合理范围。
在c语言中,位域一般用于结构体里面
话不多说,直接上代码
- #include
- #include
-
- struct Data
- {
- unsigned int num1 : 1;//1个位 ,二进制为1,也就是只能表示0或者1
- unsigned int num2 : 2;//2个位,二进制为00或者11 0->3
- unsigned int num3 : 3;//3个位 000 111 0->7
- };
-
- void main()
- {
- printf("%d\n", sizeof(struct Data));
- system("pause");
- }
运行结果:
后面再来说说怎么计算位域结构体的大小,再说一点就是,位域就相当于是限制了数据大小,不可越界,比如下面的代码
- #include
- #include
-
- struct Data
- {
- unsigned int num1 : 1;//1个位 ,二进制为1,也就是只能表示0或者1
- unsigned int num2 : 2;//2个位,二进制为00或者11 0->3
- unsigned int num3 : 3;//3个位 000 111 0->7
- };
-
- void main()
- {
- struct Data data1;
- data1.num1 = 2;
- printf("%d\n", data1.num1);
- system("pause");
- }
上面会打印结果:
一旦越界就不会打印我们想要的结果。
- #include
- #include
-
- union MyUnion1
- {
- char bj[5];//5
- int num;
- };
-
- union MyUnion2
- {
- char bj[5];
- int num[2];
- };
-
- struct stu
- {
- //联合体的大小就是占用最大的数据类型大小,但必须被最宽基本类型整除
- union{
- char bj[5];
- int bh[2];//
- }class;//8个字节//0 8
- char xm[8];//8 8
- float cj;//16 4
- };//16 + 4 = 20
-
- //这里按照结构体字节对齐来考虑
- struct test
- {
- char f1 : 3;//0 1
- short f2 : 4;//2 2
- char f3 : 5;//4 1
- };//5->6 才是short的整数倍
-
- struct test1
- {
- //同类型可以重合
- char num1 : 6;
- char num2 : 3;
- //上面占2个字节
- //下面重合占了四个字节
- int num3 : 5;
- int num5 : 20;//2-》4 + 4 = 8
- };//8
-
- struct test2{
- char f1 : 3;//0 1
- char f2;//非位域字段1 1//不用考虑重合
- char f3 : 5;//2 1 ->3
- };//3
-
- int main() {
- printf("%d\n", sizeof(struct test));
- printf("%d\n", sizeof(struct test1));
- printf("%d\n",sizeof(struct test2));
- getchar();
- return 0;
- }
运行结果:
1.先来看读取一个整数
- #include
- #include
-
-
- struct bit
- {
- unsigned char ch1 : 1;
- unsigned char ch2 : 1;
- unsigned char ch3 : 1;
- unsigned char ch4 : 1;
- unsigned char ch5 : 1;
- unsigned char ch6 : 1;
- unsigned char ch7 : 1;
- unsigned char ch8 : 1;
- };//数据类型相同占用重合1个字节,刚好八个位
-
- void main()
- {
- int num = 2;
- struct bit *p = #//指向int类型的首地址
- int length = 4;//int占四个字节,也就是4
- //4 3 2 1
- while (length--) {
- //注意,数据从右往左解析的
- printf("%d%d%d%d %d%d%d%d ",
- (p + length)->ch8,
- (p + length)->ch7,
- (p + length)->ch6,
- (p + length)->ch5,
- (p + length)->ch4,
- (p + length)->ch3,
- (p + length)->ch2,
- (p + length)->ch1);
- }
- system("pause");
- }
运行结果
2.再来看一个浮点数的读取
- #include
- #include
-
-
- struct bit
- {
- unsigned char ch1 : 1;
- unsigned char ch2 : 1;
- unsigned char ch3 : 1;
- unsigned char ch4 : 1;
- unsigned char ch5 : 1;
- unsigned char ch6 : 1;
- unsigned char ch7 : 1;
- unsigned char ch8 : 1;
- };//数据类型相同占用重合1个字节,刚好八个位
-
- void main()
- {
- float num = 19.625f;
- struct bit *p = #//指向int类型的首地址
-
- int length = 4;
- //4 3 2 1
- while (length--) {
- printf("%d%d%d%d %d%d%d%d ",
- (p + length)->ch8,
- (p + length)->ch7,
- (p + length)->ch6,
- (p + length)->ch5,
- (p + length)->ch4,
- (p + length)->ch3,
- (p + length)->ch2,
- (p + length)->ch1);
- }
-
- printf("%p\n", p);
-
- system("pause");
- }
运行结果:
看一下浮点数内存图