天天看點

經典C語言位域結構體記憶體對齊

#if   1  

#include <stdio.h>

struct bit_struct

{

char a : 3;

char b : 5;

char c;

char d : 5;

};

struct bit_struct_1

{

char a : 3;

int b : 5;

char c;

short d;

};

struct bit_struct_2

{

int a : 2;

int b : 3;

int c:3;

};

struct bit_struct_3

{

int a : 4;

int b : 5;

int c : 9;

};

int main()

{

struct bit_struct temp;

struct bit_struct_1 temp_1;

struct bit_struct_2 temp_2;

struct bit_struct_3 temp_3;

temp_2.a = 1;

temp_2.b = 7;

temp_2.c = 15;

temp_3.a = 9;

temp_3.b = 0x12;

temp_3.c = 0x10f;

printf("temp_2.a=%x\ntemp_2.b=%x\ntemp_2.c=%x\n", temp_2.a, temp_2.b, temp_2.c);

printf("temp_3.a=%x\ntemp_3.b=%x\ntemp_3.c=%x\n", temp_3.a, temp_3.b, temp_3.c);

char ch[] = { 0xf2, 0xb7, 0xe3 };

char ch_1[] = { 0xf2, 0xb7, 0xe3, 0xf2, 0xb7, 0xe3, 0xf2, 0xb7, 0xe3, 0xf2, 0xb7, 0xe3 };//16

printf("sizeof struct bit_struct=%d\n", sizeof(temp));

printf("sizeof struct bit_struct_1=%d\n", sizeof(temp_1));

memcpy(&temp, ch, sizeof(ch));

memcpy(&temp_1, ch_1, sizeof(ch_1));

printf("temp.a=%x\ntemp.b=%x\ntemp.c=%x\ntemp.d=%x\n", temp.a, temp.b, temp.c, temp.d);

printf("temp_1.a=%x\ntemp_1.b=%x\ntemp_1.c=%x\ntemp_1.d=%x\n", temp_1.a, temp_1.b, temp_1.c, temp_1.d);

return 0;

}

#endif

首先分析一下以上幾個結構體的記憶體空間(以下讨論均以32機為前提)

一、

struct bit_struct

{

char a : 3;

char b : 5;

char c;

char d : 5;

};

bit_struct 結構中占記憶體最大的成員是char c占1個位元組

相同類型的位域編譯器會進行壓縮存儲空間

依據記憶體1位元組對齊得出結構體實際占3個位元組

得出如下結構

經典C語言位域結構體記憶體對齊

經過memcpy後低位址到高位址存儲空間的内容為0xf2  0xb7   0xe3

是以再經過符号位擴充(這些資料用printf進行列印的時候是當做%d來解釋的,是以會有符号位擴充,後面不再贅述)後temp.a=0x02:(010);temp.b=0xfffffffe:(1 1110);temp.c=0x03(0 0011);

二、

struct bit_struct_1

{

char a : 3;

int b : 5;

char c;

short d;

};

與第一個結構體的差別是位域的類型和一般相鄰變量的類型不再一緻

編譯器對不同類型的相鄰位域并不進行壓縮存儲,但卻對不同類型的一般寫相鄰變量進行壓縮存儲

最大的類型占4個位元組,結構體中不可壓縮的部分的存儲位置要為4的整數倍

是以結構體占12個位元組

經過memcpy後低位址到高位址的内容為0xf2 0xb7 0xe3 0xf2 0xb7 0xe3 0xf2 0xb7 0xe3 0xf2 0xb7 0xe3 

前4個位元組的第一個位元組的最低位temp_1.a=0x02:(010);中間四個位元組的最低位temp_1.b=0x07:(0x1 0111);

temp_1.c=0xffffffe3:(0xe3);temp_1.d=0xffffb7e3;

三、

struct bit_struct_2

{

int a : 2;

int b : 3;

int c:3;

};

最大資料類型int占4位元組,struct bit_struct_2占4個位元組,根據同類型相鄰位域會壓縮存儲

經典C語言位域結構體記憶體對齊

temp_2.a=0x01:(001);temp_2.b=0xffffffff:(111);temp_2.c=0xffffffff:(111);

對temp_2.c的指派雖然超出了其位域的範圍但沒有超過int類型的取值範圍,編譯器是從最低位截取進行儲存将超出的位數舍棄并沒有往高位存儲

這個資料結構的成員都沒有超過一個位元組的,就順序的存儲,如果有某個字再加上一個位域就會存儲不下會是什麼情況,會另起一個新的位元組嗎,看下面

四、

struct bit_struct_3

{

int a : 4;

int b : 5;

int c : 9;

};

首先結構體占4個位元組沒什麼疑問

檢視記憶體超過一個位元組的編譯器也是緊挨着上一個順序的向高位址存儲,結果就不再這裡列出了

雖然有些混亂,但是這幾個例子基本上把記憶體對齊和位域結構體的存儲細節列出來了

繼續閱讀