提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
对于结构体内部的成员来说,有时候一个int成员的取值是非常有限的,比如一个人的年龄最多只要8个比特位就够了。有些成员甚至只要3个比特位就够了。如果给一个整形的空间似乎有点多,这时就可以使用位段。
一、什么是位段
位段又称为位域是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。C语言中没有专门的位段类型,位段的定义要借助于结构体,即以二进制位为单位定义结构体成员所占存储空间。从而就可以按“位”来访问结构体中的成员。
位段中的位指二进制位
1. 位段的成员必须是 int 、 unsigned int 或 signed int 。2. 位段的成员名后边有一个冒号和一个数字。
struct A
{
int _a : 2;
int _b : 5;
int _c : 10;
int _d : 30;
};
二、位段的内存分配
首先明确:
printf("%d", sizeof(struct A));
答案:8
//一个例子
struct S
{
char a:3;
char b:4;
char c:5;
char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
//空间是如何开辟的?
位段的空间开辟这里全是char型那么就先开辟1个字节也就是8个比特位,那么问题来了a是从左边开始存还是从右边开始存,事实上C语言对此并没有明确的声明。对于vs环境来说从右边开始存储。a存10二进制为1010,而a只有3个空间截断后存入010,b同理存入1100.到c时开始开辟的8的比特位剩下的空间不够所以将剩下的比特位浪费掉,开辟一个新的字节。存完后如下图。
对于vs环境内一个字节内从低位往高位放入数据,当剩下的空间不够所以将剩下的比特位浪费掉,开辟新的空间。以此类推······
三:位段的作用
1.优点
其实位段设计出来他的作用和结构体是类似的,他的成员通过加上位后使得节省了空间。
2.缺点
位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
位段的跨平台问题
1. int 位段被当成有符号数还是无符号数是不确定的。2. 位段中最大位的数目不能确定。( 16 位机器最大 16 , 32 位机器最大 32 ,写成 27 ,在 16 位机器会出问题。3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是 舍弃剩余的位还是利用,这是不确定的
总结:
四。使用位段所要注意的问题总结
1)位段的类型只能是int,unsigned int,signed int三种类型,不能是char型或者浮点型;
2)位段占的二进制位数不能超过该基本类型所能表示的最大位数,即位段不能跨字节存储,比如在VC中int是占4个字节,那么最多只能是32位;
3)无名位段不能被访问,但是会占据空间;
4)不能对位段进行取地址操作;
5)若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元(这里的位段存储单元经测试在VC环境下是4个字节)开始存放;
6)若位段出现在表达式中,则会自动进行整型升级,自动转换为int型或者unsigned int。
7)对位段赋值时,最好不要超过位段所能表示的最大范围,否则可能会造成意想不到的结果。
8)位段不能跨类型存储,类型不同,也存在字节对应。
9)位段不能出现数组的形式。
五.位段的应用
在网络底层的引用:(IP分装包的一种格式)