這是給編譯器用的參數(shù)設(shè)置肖粮,有關(guān)結(jié)構(gòu)體字節(jié)對齊方式設(shè)置, #pragma pack是指定數(shù)據(jù)在內(nèi)存中的對齊方式球散。
#pragma pack (n) 作用:C編譯器將按照n個字節(jié)對齊尿赚。
#pragma pack () 作用:取消自定義字節(jié)對齊方式。
#pragma pack (push,1) 作用:是指把原來對齊方式設(shè)置壓棧蕉堰,并設(shè)新的對齊方式設(shè)置為一個字節(jié)對齊
#pragma pack(pop) 作用:恢復對齊狀態(tài)
因此可見凌净,加入push和pop可以使對齊恢復到原來狀態(tài),而不是編譯器默認屋讶,可以說后者更優(yōu)冰寻,但是很多時候兩者差別不大
如:
#pragma pack(push) //保存對齊狀態(tài)
#pragma pack(4)//設(shè)定為4字節(jié)對齊
相當于 #pragma pack (push,4)
#pragma pack (1) 作用:調(diào)整結(jié)構(gòu)體的邊界對齊,讓其以一個字節(jié)對齊皿渗;<使結(jié)構(gòu)體按1字節(jié)方式對齊>
#pragma pack ()
例如:
#pragma pack(1)
struct sample
{
char a;
double b;
};
#pragma pack()
注:若不用#pragma pack(1)和#pragma pack()括起來斩芭,則sample按編譯器默認方式對齊(成員中size最大的那個)。即按8字節(jié)(double)對齊乐疆,則sizeof(sample)==16.成員char a占了8個字節(jié)(其中7個是空字節(jié))划乖;若用#pragma pack(1),則sample按1字節(jié)方式對齊sizeof(sample)==9.(無空字節(jié))挤土,比較節(jié)省空間啦琴庵,有些場和還可使結(jié)構(gòu)體更易于控制。
應用實例
在網(wǎng)絡協(xié)議編程中仰美,經(jīng)常會處理不同協(xié)議的數(shù)據(jù)報文迷殿。一種方法是通過指針偏移的方法來得到各種信息,但這樣做不僅編程復雜咖杂,而且一旦協(xié)議有變化庆寺,程序修改起來也比較麻煩。在了解了編譯器對結(jié)構(gòu)空間的分配原則之后诉字,我們完全可以利用這一特性定義自己的協(xié)議結(jié)構(gòu)懦尝,通過訪問結(jié)構(gòu)的成員來獲取各種信息知纷。這樣做,不僅簡化了編程导披,而且即使協(xié)議發(fā)生變化屈扎,我們也只需修改協(xié)議結(jié)構(gòu)的定義即可,其它程序無需修改撩匕,省時省力鹰晨。下面以TCP協(xié)議首部為例,說明如何定義協(xié)議結(jié)構(gòu)止毕。其協(xié)議結(jié)構(gòu)定義如下:
#pragma pack(1) // 按照1字節(jié)方式進行對齊
struct TCPHEADER
{
short SrcPort; // 16位源端口號
short DstPort; // 16位目的端口號
int SerialNo; // 32位序列號
int AckNo; // 32位確認號
unsigned char HaderLen : 4; // 4位首部長度
unsigned char Reserved1 : 4; // 保留6位中的4位
unsigned char Reserved2 : 2; // 保留6位中的2位
unsigned char URG : 1;
unsigned char ACK : 1;
unsigned char PSH : 1;
unsigned char RST : 1;
unsigned char SYN : 1;
unsigned char FIN : 1;
short WindowSize; // 16位窗口大小
short TcpChkSum; // 16位TCP檢驗和
short UrgentPointer; // 16位緊急指針
};
#pragma pack()