结构体中的位域
在储存信息时,有时并不需要一个字节的空间而是只需要几个二进制位就足够了。因此在C语言中为了节省空间提高效率,因此引出了位域(也叫位段)的概念。
如下代码中:
#include<stdio.h>
typedef struct Test
{
char a : 1;
char b : 1;
char c : 1;
}Test;
void main()
{
printf("sizeof(Test) = %d\n",sizeof(Test));
}
a,b,c都是字符类型,而每个字符都只占一个比特位的空间。而字符类型空间是8个比特位,因此它们三个加起来的共占三个比特位,没有超过8个,因此结构体只需要开辟一个字节的空间就够了。
在使用位域时需注意,位域不能跨字节存储,也不能跨类型存储,并且位域的长度不能大于指定类型的固有长度。
下面一一进行解释。
#include<stdio.h>
typedef struct Test
{
char a : 1;
char b : 6;
char c : 3;
}Test;
void main()
{
printf("sizeof(Test) = %d\n",sizeof(Test));
}
对于上述代码,结构体中的a,b加起来是7个字节,一个字符类型的空间是8个比特位,a,b在占用一个字节后剩下的空间不足以存储c,由于位域不能跨字节存储,因此需要重新开辟一个字节的空间存储c,c在新开辟的一个字节的空间里占用3个比特位。因此Test类型的大小为两个字节的空间。
#include<stdio.h>
typedef struct Test
{
char a : 1; //1 + 3
int b : 1; //4
}Test;
void main()
{
printf("sizeof(Test) = %d\n",sizeof(Test));
}
对于上述代码,我们可以看出a,b的类型是不同的,由于位域不能跨字类型存储,所以存储a,b时得分别为a,b开辟空间。a为字符类型,所以需要开辟一个字节的空间,b为整型,所以需要开辟4个字节的空间。同时还要考虑到字节对齐。所以最终程序的运行结果为8.
#include<stdio.h>
typedef struct Test
{
char a : 10; //错误,不能编译通过
int b : 1;
}Test;
void main()
{
printf("sizeof(Test) = %d\n",sizeof(Test));
}
对于上述代码,程序是不能编译通过的。原因是在使用位域时需要注意位域的长度不能大于指定类型的固有长度。