假設現在有三個種類的封包要被傳送, 而同一時間只會送出這三類的其中一類封包, 同時我們用struct與union兩種方式宣告, 在執行結果進行比較所需佔用的記憶體空間。
因此程式可以這樣寫:
//*****************example_union_usage.c****************//
#include <stdio.h>
struct structA
{
int a;
char b;
};
struct structB
{
char a;
short b;
};
struct structC
{
int a;
char b;
float c;
};
struct CommuPacket //使用union的
{
int iPacketType;
union
{
struct structA packetA;
struct structB packetB;
struct structC packetC;
};
};
struct CommuPacket_2
{
int iPacketType;
struct
{
struct structA packetA;
struct structB packetB;
struct structC packetC;
};
};
int main()
{
struct CommuPacket struct_CommuPacket;
struct CommuPacket_2 struct_CommuPacket_2;
int struct_size, struct_size_2;
struct_size = sizeof(struct_CommuPacket);
struct_size_2 = sizeof(struct_CommuPacket_2);
printf("struct_CommuPacket size=%d\n", struct_size);
printf("struct_CommuPacket_2 size=%d\n\n", struct_size_2);
int m_size_packetA, m_size_packetB, m_size_packetC;
m_size_packetA = sizeof(struct_CommuPacket.packetA);
printf("packetA size is %d\n", m_size_packetA);
m_size_packetB = sizeof(struct_CommuPacket.packetB);
printf("packetB size is %d\n", m_size_packetB);
m_size_packetC = sizeof(struct_CommuPacket.packetC);
printf("packetC size is %d\n", m_size_packetC);
}
//***************************************************//
輸出結果:
可以看到使用union的,佔了16byte,與struct的28byte比較,小了許多。
========================================================================
另外你可能會有疑問,為什麼packetA,packetB,packetC的size分別是8byte,4byte,12byte?
照理說不是應該是5byte,3byte,9byte嗎?
這就要講到struct的"自然對齊"(natural alignment)特性與"指定對齊":
一. natural alignment,是指按結構體的成員中size最大的成員對齊。
舉個例子:
struct natural_alignment
{
char a;
short b;
char c;
};
在上述struct中,size最大的是short,其長度為2byte,因而結構中的char成員a、c都以2為單位對齊,sizeof(natural_alignment)的結果等於6;
如果改為:
struct natural_alignment
{
char a;
int b;
char c;
};
其結果顯然為12。
二. 還有另外一種用法名為"指定對齊"
通常可以通過下面的方法來改變指定對齊的條件:
• 使用虛擬指令#pragma pack (n),編譯器將按照n個位元組對齊;
• 使用虛擬指令#pragma pack (),取消自定義位元組對齊方式
*如果#pragma pack (n)中指定的n大於結構體中最大成員的size,則沒有作用,結構體仍然按照size最大的成員進行對齊。
例如:
#pragma pack (n)
struct natural_alignment
{
char a;
int b;
char c;
};
#pragma pack ()
當n為4、8、16時,其對齊方式都一樣,sizeof(naturalalign)的結果都等於12。而當n為2時,sizeof(naturalalign)的結果為8。
在VC++ 6.0編譯器中,我們可以指定其對齊條件,其操作方式為依次選擇projetct > setting > C/C++功能表,在struct member alignment中指定你要的對齊條件。
另外,通過__attribute((aligned (n)))也可以讓所作用的結構體成員對齊在n位元組邊界上,但是它較少被使用。
沒有留言:
張貼留言