标签:展示 地址 通过 定位 声明 无法定位 无法 读取 字节
位域在实际开发中可能用的比较少,但是对于理解内存存储数据非常有帮助!
我们可以在结构体或共用体中描述一个简单的位域:
struct
{
char a:1;
char b:1;
char c:1;
}st;
首先我们先说说这个结构体在内存中所占的大小
st变量占用了1个字节,但只有3位(bit)用来存储数据。当然如果用的是int类型,将会占用4个字节,这是字节对齐的缘故。1字节(byte)=8位(bit),位是计算机中最小数据存储单位。
数据是怎么存放的呢?
在计算机中内存都会有内存地址,每个内存地址对应的是一个字节。像指针和sizeof都是无法定位位域变量的,但是每个单位地址中的位也是有标记的。我们可以把单位地址比作是门牌号,而这个门牌号对应的是数据的居住所,这个居住所有连续的8间房子,这些房子都只有一个出入口,且一次只允许一个数据(o或1)通过。有了这些限定条件之后,就容易明白数据存放的规律。我们可以把这八间房子标做0-7。
假设数据从左侧开始写入,那么首先写入的数据存放在最右侧,等到数据写入完,未写入的位补0。
据上所述,每个位都是有标记的,所以在读取位域时,可以准确读取指定位置的位。
*我们使用位域与共用体和结构体做个小例子来理解
事先声明:由于计算机中有符号的整数都以补码形式存在,而不会出现像初期原码表示带符号的数字存在两个0(+0与-0),所以把原码中表示-0的数字来表示最大的负数。也就是当只有符号位为1时,代表符号位的1也算到数字位中去了。二进制10表示有符号位十进制-2、二进制1表示有符号十进制-1等等。
union
{
struct
{
char a:1;
char b:1;
char c:1;
}st;
char y;
}un; //声明共用体变量名为un
int main()
{
un.y = 1; //对共用体中的char类型进行赋值
printf("%d %d %d\n",un.st.a,un.st.b,un.st.c); //对结构体中的值进行打印
}
结果:
-1 0 0
这个共用体的大小位为1字节,对un.y赋值为1,1转为二进制还是1,其他位补0,我们把数据在内存中的分布进行展示:
可以看到除了序号为0的位是1,其他位都是0。如果对un.y赋值为3呢?
把代码输完一运行
结果:
-1 -1 0
数据在内存的分布应该是这样的
3转为二进制就是11,其他位补0,就是这样的结果了。
关于位域就分享到这了,大家也可以把类型换成其他的,也是一样的道理。可以都尝试一下,对内存存放数据一定会有深刻的理解。如果上述有什么问题可以留言评论!
标签:展示 地址 通过 定位 声明 无法定位 无法 读取 字节
原文地址:https://www.cnblogs.com/tansss/p/12483533.html