位元組對齊的原因
為了提高 cpu 的儲存速度,編譯器會對 struct 和 union的儲存進行優化,即進行位元組對齊。
對齊方式
對於 struct 或 union 中的 struct 或者 union 來說,它們的位元組對齊標準就是它的所有成員中位元組數最大的資料的位元組數。
一般情況下 c/c++ 的變數所占用的位元組數
char: 1位元組;
short: 2位元組;
int: 4位元組;
long: 4位元組;
long long: 8位元組;
float: 4位元組;
double: 8位元組;
bool: 1位元組;
*struct 中位元組對齊需要滿足的條件:
1、某個變數存放的起始位置相對於結構的起始位置的偏移量是該變數位元組數的整數倍
2、結構所佔的總位元組數是該結構中位元組數最長的變數的整數倍
struct struct
a;
sizeof(a) = 8 + 1 + 3 + 4 = 16。其中補上的 3 個位元組是為了讓 int 型資料的起始位置相對於結構起始位置的偏移量為 4 的整數倍。
struct struct
b;
sizeof(b) = 1 + 7 + 8 + 4 = 20。 20 / 8 = 2 …… 4,所以需要再補上 4 個位元組,使之成為 8 的 整數倍
*union 中位元組對齊需要滿足的兩個條件:
1) union的大小必須足夠容納位元組數最大的變數
2)union的大小需要能夠被其所包括的基礎成員型別的大小所整除
位元組對齊的另一種方式
vc提供了 #pragma pack(n) 用來自定義位元組對齊方式
有一下兩種情況:
1、n 大於變數的位元組數:偏移量只滿足預設的位元組對齊方式;
2、n 小於變數所佔的位元組數:偏移量是 n 的整數倍,不使用預設的位元組對齊方式。
#pragma pack(push) // 保持對齊狀態
#pragma pack(4) // 設定為 4 位元組對齊
struct test
a;#pragma pack(pop) // 恢復對齊狀態
sizeof(a) = 1 + 3 + 8 + 4 = 16 // 其中補上三位是因為 n 小於 8,所以 m2 的起始位置相對於結構起始位置的偏移量是 n,即為 4.
#pragma pack(8)
struct s1
;struct s2
;#pragma pack()
sizeof(s1) = 1 + 3 + 4 = 8
sizeof(s2) = 1 + 3 + 8 + 4 + 8 = 24。// 其中加上的 4 是因為變數 e 的位元組數是 8 ,其相對與起始位置的偏移量必須是 8 的倍數。
位元組對齊問題的討論到上邊已經結束了。下面再加上我碰到的兩道題目作為例項:
#include union
a;int main()
輸出為 266 8
解析:對 union 分配記憶體涉及位元組對齊問題,在上方已有詳細描述,在此只簡單解釋一番。union 分配的記憶體必須是 union 中所有基本資料型別的倍數。
在此題中即為 1 和 4 的倍數,又 char x[5] 占用 5 個位元組,故 union 分配的記憶體大小應為 8 個位元組。
windows 系統中高位元組在後,低位元組在前。而 char x[5] 只有前兩個元素有值,即兩個值只佔 2 個位元組,也即 union 中的 int 型資料中只有低兩位上有值。
即 i 的二進位制表示為:
00000000 00000000 00000001 00001010
即: 2^1 + 2^3 + 2^8 = 266
也相當於十六進製制 0x010a, 即: 10 * 16^0 + 1 * 16^2 = 266
C C 位元組對齊
什麼是對齊,以及為什麼要對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各...
c c 位元組對齊
什麼是對齊,以及為什麼要對齊 現代計算機中記憶體空間都是按照byte劃分的,從理論上講似乎對任何型別的變數的訪問可以從任何位址開始,但實際情況是在訪問特定變數的時候經常在特定的記憶體位址訪問,這就需要各型別資料按照一定的規則在空間上排列,而不是順序的乙個接乙個的排放,這就是對齊。對齊的作用和原因 各...
C C 位元組對齊
概念 對齊跟資料在記憶體中的位置有關。如果乙個變數的記憶體位址正好位於它長度的整數倍,他就被稱做自然對齊。比如在32位cpu下,假設乙個整型變數的位址為0x00000004,那它就是自然對齊的。為什麼位元組需要對齊 根本原因在於cpu訪問資料的效率問題。假設上面整型變數的位址不是自然對齊,比如為0x...