文檔聲明:
以下資料均屬于本人在學(xué)習(xí)過程中產(chǎn)出的學(xué)習(xí)筆記,如果錯誤或者遺漏之處,請多多指正。并且該文檔在后期會隨著學(xué)習(xí)的深入不斷補(bǔ)充完善。
資料僅供學(xué)習(xí)交流使用。
作者:Aliven888
1、簡述
? 結(jié)構(gòu)體(struct)是一種集合,它里面包含了多個(gè)變量或數(shù)組,它們的類型可以相同,也可以不同,每個(gè)這樣的變量或數(shù)組都稱為結(jié)構(gòu)體的成員(Member)。
2、定義格式
常用格式:
struct MyStructName
{
參數(shù)類型 參數(shù); //例如:int a;
... //參數(shù)可有多個(gè),而且類型不同
};
**直接定義一個(gè)結(jié)構(gòu)體變量(全局可以用):
struct MyStructName
{
參數(shù)類型 參數(shù); //例如:int a;
... //參數(shù)可有多個(gè),而且類型不同
}stu; //該結(jié)構(gòu)體變量 stu 可以直接使用
**定義唯一結(jié)構(gòu)體變量(全局可以用):
struct MyStructName
{
參數(shù)類型 參數(shù); //例如:int a;
... //參數(shù)可有多個(gè),而且類型不同
}stu; //該結(jié)構(gòu)體變量 stu 是唯一的
為結(jié)構(gòu)體定義一個(gè)別名:
typedef struct MyStructName
{
參數(shù)類型 參數(shù); //例如:int a;
... //參數(shù)可有多個(gè),而且類型不同
}stu_MyStuName; //可以使用stu_MyStuName定義結(jié)構(gòu)體變量
eg : stu_MyStuName st; //使用別名定義結(jié)構(gòu)體對象 st
3、結(jié)構(gòu)體的使用
首先我們定義一個(gè)結(jié)構(gòu)體:
struct MyStruct //因?yàn)槭桥e例,定義的比較簡單
{
int a;
};
定義結(jié)構(gòu)體對象與訪問參數(shù):
//C 語言中的定義方式
struct MyStruct obj; //或者指針形式:struct MyStruct *obj;
//C++中支持的定義方式
MyStruct obj; //或者指針形式:MyStruct *obj;
//參數(shù)訪問 指針形式訪問
obj.a = 0x01; // obj->a = 0x01;
4、結(jié)構(gòu)體內(nèi)存計(jì)算
struct MyStruct
{
byte bValue;
WORD wValue;
int iValue;
double dbValue;
MyStruct()
{
bValue = 0x00;
wValue = 0x00;
iValue = 0x00;
dbValue = 0.0;
}
}stu;
void test()
{
cout << "stu len = " << sizeof(stu) << endl;
}

? 我們運(yùn)行上面的代碼發(fā)現(xiàn),結(jié)構(gòu)體的長度并不是我們想象的 1 + 2 + 4 + 8 = 15,而是 16,其實(shí)這就是由于字節(jié)對齊導(dǎo)致的。
計(jì)算機(jī)實(shí)際在計(jì)算該結(jié)構(gòu)體長度的流程是:
1、首先計(jì)算 byte bValue 占 一個(gè) 字節(jié)。 //len = 1
2、計(jì)算 WORD wValue 時(shí),發(fā)現(xiàn) len 和 2 不是整數(shù)倍關(guān)系,所以對 a 進(jìn)行了補(bǔ)齊,此時(shí) a 占用兩個(gè)字節(jié)。 //len = 2 + 2 = 4
3、計(jì)算 int iValue 時(shí),len 剛好和 4 是整數(shù)倍關(guān)系 // len = 4 + 4 = 8
4、計(jì)算 double dbValue 時(shí),len 剛好和 8 是整數(shù)倍關(guān)系 // len = 8 + 8 = 16。
5、自定義字節(jié)對齊
? 通過第四小節(jié)我們發(fā)現(xiàn),計(jì)算機(jī)系統(tǒng)會對結(jié)構(gòu)進(jìn)行自動字節(jié)對齊,到時(shí)我們得到的結(jié)構(gòu)體長度并不會是我們期望中的長度。那么有什么方法可以滿足我們得到期望中的長度呢? 其實(shí)很簡單,我們可以通過自定義字節(jié)對齊的方式,讓最終得到的結(jié)構(gòu)體長度等于我們的期望值。
這里我們可以通過使用的下面的方法來實(shí)現(xiàn):
#pragma pack(push):
?英文單詞push是“壓入”的意思。編譯器編譯到此處時(shí)將保存對齊狀態(tài)(保存的是push指令之前的對齊狀態(tài))。
#pragma pack(n):
?這樣就可以知道,當(dāng)我們想要一個(gè)結(jié)構(gòu)體按照4字節(jié)對齊時(shí),可以使用#pragma pack(4) ,如果又想使用默認(rèn)對齊方式時(shí),可以使用#pragma pack() 。
#pragma pack(pop):
?英文單詞pop是”彈出“的意思。編譯器編譯到此處時(shí)將恢復(fù)push指令前保存的對齊狀態(tài)(請?jiān)谑褂迷擃A(yù)處理命令之前使用#pragma pack(push))。
注意事項(xiàng):
?push和pop是一對應(yīng)該同時(shí)出現(xiàn)的名詞,只有pop沒有push不起作用,只有push沒有pop可以保持之前對齊狀態(tài)(但是這樣就沒有使用push的必要了)。
使用格式:
#pragma pack(push)
#pragma pack(4)
struct MyStruct
{
....
};
#pragma pack(pop)
?這樣在push和pop之間的結(jié)構(gòu)體就可以按照pack指定的字節(jié)(這里是4字節(jié)對齊方式),而pop之后的結(jié)構(gòu)體按照#pragma pack(push) 前對齊方式。
#pragma pack(push)
#pragma pack(1)
struct MyStruct
{
byte bValue;
WORD wValue;
int iValue;
double dbValue;
MyStruct()
{
bValue = 0x00;
wValue = 0x00;
iValue = 0x00;
dbValue = 0.0;
}
}stu;
#pragma pack(pop)
void test()
{
cout << "stu len = " << sizeof(stu) << endl;
}
此時(shí),我們在運(yùn)行上面的代碼發(fā)現(xiàn),結(jié)構(gòu)體的長度就是 1 + 2 + 4 + 8 = 15了。
