c 語言結構體及位域記憶體大小
小白一枚,最近線學習野火stm32,寫個部落格記錄下自己學習之路。
以下資料來自野火論壇以及其他**。
存對齊的規則很簡單:
1.起始位址為該變數型別所佔記憶體的整數倍,若不足則不足部分用資料填充至所佔記憶體的整數倍。
2.該結構體所佔總記憶體為結構體成員變數中最大資料型別的整數倍。
一.看如下例子:(假設char 是 1個位元組,double是8個位元組,int是2個位元組 ,float4位元組)
typedef struct
test;
求sizeof(test)的值?
答案:1+7 +8 = 16;
typedef struct
test;
求sizeof(test)的值?
答案:1+7+8+4+4=24;(最後還加了4是因為總長度是8的整數倍,所以補齊+4);
當結構體中的變數的位置變化時,其結果也會不一樣哦~
typedef struct
test;
答案是:8+1+3+4=16;
#pragma pack(4) //規定以4位元組對齊
typedef struct
test;
求sizeof(test)的值?
答案:1+3+8+4=16;
現在再插個聯合體試試 = =
struct stu
class;
char xm[8];
float cj;
}xc;
//則 sizeof(xc)的值為?
答案:聯合體占用5位元組 但是對齊方式int(2位元組),所以再加1,為6;接著6+8位14位元組,為了對齊float的4位元組,這裡補充2位元組,最後的結果是:5+1+8+2+4=20;
現在再進一步看看:
struct stu
class;
char xm[8];
float cj;
}xc;
//若 xc 位址為0x1000 則求 &xm[0] 的值?
答案:0x1000+6=0x1006;
二.位域
使用位域的主要目的是壓縮儲存,其大致規則為:
1) 如果相鄰位域字段的型別相同,且其位寬之和小於型別的 sizeof 大小,則後面的字段將緊鄰前乙個字段儲存,直到不能容納為止*
2) 如果相鄰位域字段的型別相同,但其位寬之和大於型別的 sizeof 大小,則後面的字段將從新的儲存單元開始,其偏移量為其型別大小的整數倍;
3) 如果相鄰的位域字段的型別不同,則各編譯器的具體實現有差異,vc6 採取不壓縮方式,dev-c++採取壓縮方式;
4) 如果位域字段之間穿插著非位域字段,則不進行壓縮;
5) 整個結構體的總大小為最寬基本型別成員大小的整數倍。
例子:
struct test
;求 sizeof(test)大小?
這個好像比較簡單:3+4,佔了7位了,再來個5的話,乙個位元組就塞不住了,所以f3存入下乙個位元組,總的也就是2位元組。
當存在非位域的字段時,則不會進行壓縮。
struct c;
求 sizeof(test)大小
答案:1+1+1=3;
所以一般情況下占用空間小的型別排在前面,占用空間大的型別排在後面,這樣可以相對節約一些對齊空間 。
*第一次寫,不足之處還請指正~~~~*
C語言中結構體占用記憶體大小
這個問題很經典,很容易出現,也叫記憶體的4k對齊吧 cpu傳輸資料的方式 cpu每次傳輸資料大小由它的總線條數決定,32位傳輸4個位元組,64位傳輸8個位元組。這裡以64位系統舉例,若宣告乙個變數大小為8位元組,起始位址位1,而cpu讀取的位址為0 7,則該變數需要讀取兩次,顯然降低了cpu的效能。...
結構體記憶體大小對齊原則 位域
結構體中成員變數分配的空間是按照成員變數中占用空間最大的來作為分配單位,同樣成員變數的儲存空間也是不能跨分配單位的,如果當前的空間不足,則會儲存到下乙個分配單位中。補充 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除。結構體每個成員相對於結構體首位址的偏移量 offset 都是成員大小的整數...
結構體的大小及結構體之位域
結構體的大小 規則1 結構體的大小等於結構體內最大型別的整數倍 規則3 為了滿足規則1和2在結構體成員之後進行位元組填充 結構體位域的大小規則 共用體 為了提速之類的,在結構體和聯合體的記憶體塊中,是按照一定的規則安排的 聯合體 聯合體的記憶體不會為了所有成員安排,而是只取最大的成員的所需記憶體大小...