首先我們大家先思考乙個問題,為什麼編譯器會有記憶體對齊這種東西呢?
原因有二:
一.平台原因:
某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常。
二.效能原因:
如果訪問的是未對齊的記憶體,處理器需要做兩次記憶體訪問;如果記憶體對齊,則處理器只需要做一次記憶體訪問。
許多計算機系統對基本型別資料在記憶體中存放的位置有限制,它們會要求這些資料的首位址的值是某個數k(通常為4或8)的倍數,這就是所謂的記憶體對齊,而這個k則被稱為該資料型別的對齊模數。
記憶體對齊的規定:
1.資料成員對齊規則:結構的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員自身大小的整數倍開始。
2.結構體作為成員:
如果是兩個結構體巢狀在一起,則在計算位元組大小的時候應該先找出第乙個最大對齊模數和第二個函式體的最大對齊模數比較,找出最大的那個數,就是整個函式的最大對齊模數,然後用它的整數倍計算儲存。
3.結構體成員相對首位址偏移量必須是成員大小的整數倍,也就是記憶體對齊。
4.結構體總大小必須是對齊模數的整數倍。
記憶體對齊只能加不能減,在儲存型別不同的資料的時候,它們所佔的位元組大小也不同,在計算時是看前邊所有資料之和是否為k的倍數,而不是從上一節補。
位域
什麼是位域?
位域就是把乙個位元組中的二進位制劃分為幾個不同的區域,並說明每個區域的位數。
一.位域的定義和位域的變數說明與結構體定義相仿,形式為:
struct 位域結構名 ;
其中位域列表的形式為: 型別說明符 位網域名稱:位域長度
ex:struct a ;
位域的儲存要求
1,乙個位域必須存在同乙個位元組中,不能跨越兩個位元組(1個位元組8個位)。
ex:struct a ;
2.位域可以無位網域名稱,這時它只能用做填充或調整位置,不能使用。
ex:char :2 //該2 位不能使用
在計算位域的大小時,如果位域字段穿插著非位域字段,則不進行壓縮。
ex:
struct b
char c:1;
double i;
int c2:4;
cout<
struct b
char c:1;
int c2:4;
double i;
}; cout<
記憶體對齊和位域
結構體的記憶體結構 當我們解決實際問題時,我們會發現編譯器提供給我們的內建型別其實不夠用,沒有辦法用同一種型別儲存多種型別的資料,c語言中有自己的自定義型別,比如結構 位域 聯合 列舉 typedef關鍵字等。下面我就簡單的介紹一下結構和位域。結構 在乙個名字下的一組變數,有時也稱為聚集資料型別。位...
位域位元組對齊
使用位域的主要目的是壓縮儲存,其大致規則為 1 如果相鄰位域字段的型別相同,且其位寬之和小於型別的sizeof大小,則後面的字段將緊鄰前乙個字段儲存,直到不能容納為止 2 如果相鄰位域字段的型別相同,但其位寬之和大於型別的sizeof大小,則後面的字段將從新的儲存單元開始,其偏移量為其型別大小的整數...
結構體記憶體大小對齊原則 位域
結構體中成員變數分配的空間是按照成員變數中占用空間最大的來作為分配單位,同樣成員變數的儲存空間也是不能跨分配單位的,如果當前的空間不足,則會儲存到下乙個分配單位中。補充 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除。結構體每個成員相對於結構體首位址的偏移量 offset 都是成員大小的整數...