#pragma pack(push,1)與#pragma pack(1)的區別(轉)


這是給編譯器用的參數設置,有關結構體字節對齊方式設置, #pragma pack是指定數據在內存中的對齊方式。

#pragma pack (n)             作用:C編譯器將按照n個字節對齊。
#pragma pack ()               作用:取消自定義字節對齊方式。


#pragma  pack (push,1)     作用:是指把原來對齊方式設置壓棧,並設新的對齊方式設置為一個字節對齊

#pragma pack(pop)            作用:恢復對齊狀態

因此可見,加入push和pop可以使對齊恢復到原來狀態,而不是編譯器默認,可以說后者更優,但是很多時候兩者差別不大

如:

#pragma pack(push) //保存對齊狀態

#pragma pack(4)//設定為4字節對齊

  相當於 #pragma  pack (push,4)  

 

#pragma  pack (1)           作用:調整結構體的邊界對齊,讓其以一個字節對齊;<使結構體按1字節方式對齊>

#pragma  pack ()

例如:

1 #pragma pack(1)
2 
3 struct sample
4 {
5 char a;
6 double b;
7 };
8 
9 #pragma pack()

 

注:若不用#pragma pack(1)和#pragma pack()括起來,則sample按編譯器默認方式對齊(成員中size最大的那個)。即按8字節(double)對齊,則sizeof(sample)==16.成員char a占了8個字節(其中7個是空字節);若用#pragma pack(1),則sample按1字節方式對齊sizeof(sample)==9.(無空字節),比較節省空間啦,有些場和還可使結構體更易於控制。

應用實例

在網絡協議編程中,經常會處理不同協議的數據報文。一種方法是通過指針偏移的方法來得到各種信息,但這樣做不僅編程復雜,而且一旦協議有變化,程序修改起來也比較麻煩。在了解了編譯器對結構空間的分配原則之后,我們完全可以利用這一特性定義自己的協議結構,通過訪問結構的成員來獲取各種信息。這樣做,不僅簡化了編程,而且即使協議發生變化,我們也只需修改協議結構的定義即可,其它程序無需修改,省時省力。下面以TCP協議首部為例,說明如何定義協議結構。其協議結構定義如下: 

 1 #pragma pack(1) // 按照1字節方式進行對齊
 2 struct TCPHEADER 
 3 {
 4      short SrcPort; // 16位源端口號
 5      short DstPort; // 16位目的端口號
 6      int SerialNo; // 32位序列號
 7      int AckNo; // 32位確認號
 8      unsigned char HaderLen : 4; // 4位首部長度
 9      unsigned char Reserved1 : 4; // 保留6位中的4位
10      unsigned char Reserved2 : 2; // 保留6位中的2位
11      unsigned char URG : 1;
12      unsigned char ACK : 1;
13      unsigned char PSH : 1;
14      unsigned char RST : 1;
15      unsigned char SYN : 1;
16      unsigned char FIN : 1;
17      short WindowSize; // 16位窗口大小
18      short TcpChkSum; // 16位TCP檢驗和
19      short UrgentPointer; // 16位緊急指針
20 }; 
21 #pragma pack()

轉自:http://blog.csdn.net/vblittleboy/article/details/6935165


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM