文章前言:
本篇文章是关于结构体的进阶知识,主要介绍位断。
对了,在看这篇文章之前,我希望你可以先了解关于结构体大小的机制,下面是我的一篇关于此的文章。
结构体大小
初见位断:
typedef struct A
{
char a : 2;
int b : 5;
int c : 10;
int d : 30;
}A;
//这里的A就是一个位断类型
我觉得,当你看到冒号可能会感到疑惑,如果感到疑惑,那你可以看看这篇文章,我相信会让你对位断有所了解。
位断的声明:
首先简单介绍位断:
来,逐字分析法!
位 —— 二进制位
断 —— 在二进制位的相应位置断开,不同于结构体的断开是一字节一字节的,这里的断是1bit1bit地断开。也因此,在位断中没有对齐数的说法,因而,位断可以在面对较小数据时,在只能使用固定数据类型的情况下节省空间。
从上端代码我们可以清晰地知道:位断的外结构就是一个结构体
因此,位断的声明和结构体十分类似,但有两点不同:
1、 位断的成员必须是int (其实在一些编译器上char也是可以的),包括符号类型和无符号类型。
2、 位段的成员名后边有一个冒号和一个数字。
位断的内存分配:
想要知道一个位断类型的大小,就必须了解其内存分配机制。
幸运的是,位断的内存分配机制与结构体的相类似,上面的链接也有助你了解结构体的内存分配机制。
请看下端代码
typedef struct A
{
char a : 2;
char b : 2;
int d : 30;
}A;
int main()
{
A s = { 0 };
s.a = 1;
s.b = 10;
s.d = 1;
printf("%x %x", s.a, s.b);//猜猜结果多少?
}
给出自己的答案了吗?可能会让你大跌眼镜。
来分析吧!
我先给出规则:
1、在位断中,内存的分配是以bit为单位的。
2、代码从上到下,依次按照变量的类型以4个字节( int )或者1个字节( char )的方式来开辟空间。(在VS中好像是一律以4个字节开辟,不确定)
3、在一个变量已经占好位置后,若剩下的空间比下一个变量要小,则直接开辟新的空间。特别要注意的是,在一次已经开辟的空间中,变量是从高地址向低地址占内存,而内存的开辟是从低地址到高地址。
首先是char a:
然后是char b:
最后是int d:
这样就分析完毕了。附上内存数值图:
9是怎么来的?
对于09,它的二进制其实就是00001001,
对应的十六进制:0000 -> 0 1001 -> 9,这下明白了吗?
而在本案例中,明显A的大小为8字节。