位域在內存中的存放
位域在實際開發中可能用的比較少,但是對於理解內存存儲數據非常有幫助! 我們可以在結構體或共用體中描述一個簡單的位域: ``` 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,就是這樣的結果了。
關於位域就分享到這了,大家也可以把類型換成其他的,也是一樣的道理。可以都嘗試一下,對內存存放數據一定會有深刻的理解。如果上述有什么問題可以留言評論!