碼字不易,對你有幫助點讚/**/關注支援一下作者不會程式設計的程式圓看更多乾貨,獲取第一時間更新如果想看比較好看的排版,可以閱讀原文【c高階 四】記憶體對齊mp.weixin.qq.com
我們這一節主要來講一相關的些比較重要的知識。
struct s1
;
上面是乙個結構體,也是我們自定義的一種型別。我們知道,任何型別都有大小,那麼結構體 s1 的大小是多少?
是結構體各成員變數大小的和嗎?如果是的話,那結構體 s1 的大小就是 6
那我們設計乙個程式驗證一下:
int main(void)
輸出是:12,這個 12 是怎麼得來的呢?
想要知道這個問題答案,那我們就要了解一下記憶體對齊。
記憶體對齊關係到 cpu 讀取資料的效率 和 一些其他原因。我們這裡不做展開,有興趣可以自己查一下。
對齊數= 編譯器預設的乙個對齊數 與 該成員大小的較小值。
vs中預設的值為8
判斷下面結構體的大小:
vs 預設的對齊數是 8,32 位機器
1
struct s1
;
解析:1(char)
(+3
(int 應該對齊到 4 的整數倍上,也就是 4,所以應該給 1 加上 3 湊成 4)) +4(int)
+1(char)
(+3
最後整個結構體大小為最大對齊數(也就是 4)的整數倍處,所以結構體的大小不是 9 而是 12 )(最大對齊數是最大成員的對齊數,這個是前面算過的(成員大小和預設對齊數取小))
答案:12
2
struct s2
;
第乙個例題已經詳細的分析了判斷結構體大小的步驟,下面不再贅述。
1 (char)
+1 (char)
(+2
) +4 (int)
答案:8
3
struct s3
8 (double)
+1 (char)
(+3
) +4 (int)
答案:16
4
struct s3
;struct s4
;
例 3 中,我們已經知道了 s3 的大小是 16
1 (char)
(+7
(結構體大小是 16 和 編譯器預設對齊數 8 取較小值,所以結構體要對齊的整數倍是 8)) +16 (s3)
+8 (double)
答案:32
不確定你可以自己在你的編譯器上敲一下,看看執行結構,前提是編譯器的預設對齊數是 8 ,如果不是,結果可能會不一樣,那麼編譯器的預設對齊數可以修改嗎?
#pragma pack(4)//設定預設對齊數為4
如果你想取消設定的預設對齊數,還原為預設:
#pragma pack()
位段的宣告和結構是類似的,有兩個不同:
位段的成員必須是 int、unsigned int 或signed int 。
位段的成員名後邊有乙個冒號和乙個數字。
struct s
;int main(void) ;
// 可以像一般的結構體成員訪問一樣訪問它們
s.a = -4;// 3 個位元組儲存數的範圍是 -4 ~ 3
s.b = 7;
s.c = 3;
s.d = 4;
printf("%dn", s.a);
return 0;
}
儲存方式:位段的成員可以是 int unsigned int signed int 或者是 char (屬於整形家族)型別
位段的空間上是按照需要以4個位元組( int )或者1個位元組( char )的方式來開闢的。
位段涉及很多不確定因素,位段是不跨平台的,注重可移植的程式應該避免使用位段
位段的應用:
可以自行了解ip資料報格式。
在 github 上看更全的目錄:以上就是本次的內容。以後的這個系列的**都會上傳上去,歡迎 star
關注我,看更多乾貨!
我是程式圓,我們下次再見。
整數邊界對齊方式 c中結構體邊界對齊
原則1 普通資料成員對齊規則 第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小的整數倍開始 比如int在32位機為 位元組,則要從4的整數倍位址開始儲存 原則2 結構體成員對齊規則 如果乙個結構裡有某些結構體成員,則該結構體成員要從其內部最大元素大小的整數倍位址...
整數邊界對齊方式 帶你深入理解記憶體對齊最底層原理
相信絕大多數的人都了解記憶體對齊,對齊後效能高。但是其最最底層的原理是啥呢?有的人可能會說,因為快取記憶體的工作機制。讀者你很聰明,這是原因之一。但我今天想挖的是更底層一點的原理,讓我們去記憶體的物理構成裡找找答案!圖1 記憶體外形圖 乙個記憶體是由若干個黑色的記憶體顆粒構成的。每乙個記憶體顆粒叫做...
整數邊界對齊方式 嵌入式基礎 位元組對齊
一 記憶體訪問對齊規則 從高階語言的視角看,記憶體訪問是是位元組為單位的。但是從cpu角度看,記憶體訪問粒度與指令有關,比如1位元組訪問,2位元組訪問,4位元組訪問,8位元組訪問等。如果在程式設計過程中不注意記憶體對齊,可能引發一系列問題 1,非對齊訪問需要硬體修正。比如讀取4位元組資料,如果從4位...