结构体对齐规则(1)-(5)基本规则;(6)-(7)关于pack值
(1)struct总长度是其最宽的元素的长度的整数倍
struct st_1
{
char ch1;
short sh2;
int i3;//最宽 size=4
};
printf("sizeof st_1=%d\n",sizeof(st_1));
打印:
sizeof st_1=8
(2)成员中有数组,宽度按照单个元素计算
struct st_0
{
char ch[2];//数组宽度2 单个元素宽度1
char chx;
};
printf("sizeof st_0=%d\n",sizeof(st_0));
打印:
sizeof st_0=3
(3)空结构体的大小不为0,而是1
struct st_0_2 {};
printf("sizeof st_0_2=%d\n",sizeof(st_0_2));
打印:
sizeof st_0_2=1
(4)结构体变量的首地址能够被其最宽基本类型成员的大小所整除
//继续使用(2)中的st_0
//继续使用(1)中的st_1
st_1 _st1;
st_0 _st0;
st_1 _st1_2;
printf("address of _st1=%u %u/sizeof(_st1) =%.2f\n", &_st1, &_st1, (float)(((unsigned int)(&_st1)) / (sizeof(_st1) * 1.0f)));
printf("address of _st0=%u %u/sizeof(_st0) =%.2f\n", &_st0, &_st0, (float)(((unsigned int)(&_st0)) / (sizeof(_st0) * 1.0f)));
printf("address of _st1_2=%u %u/sizeof(_st1_2)=%.2f\n", &_st1_2, &_st1_2, (float)(((unsigned int)(&_st1_2)) / (sizeof(_st1_2) * 1.0f)));
打印:
address of _st1=3865312 3865312/sizeof(_st1) =483164.00 //能够整除最长元素int
address of _st0=3865300 3865300/sizeof(_st0) =1288433.38 //没有整除,但可被1整除说明按照char宽度对齐地址
address of _st1_2=3865284 3865284/sizeof(_st1_2)=483160.50 //没有整除整个结构宽度,但整除int的宽度
(5)每个元素起始于元素宽度的整倍数
//继续使用(1)中的st_1
#define OFFSETOF(STRUCT,MEMBER) ((unsigned int)(&(((STRUCT*)0)->MEMBER)))
printf("offset of ch1 in st_1 = %d\n", OFFSETOF(st_1, ch1));
printf("offset of sh2 in st_1 = %d\n", OFFSETOF(st_1, sh2));
printf("offset of i3 in st_1 = %d\n", OFFSETOF(st_1, i3));
打印:
offset of ch1 in st_1 = 0
offset of sh2 in st_1 = 2
offset of i3 in st_1 = 4
(6)#pack值为1、2、4、8、16,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准
#pragma pack(push)
#pragma pack(2)
struct st_3
{
short sh1;
double d2;
char ch3;
int i4;
};
#pragma pack(pop)
printf("sizeof st_3=%d\n", sizeof(st_3));
printf("offset of sh1 in st_3 = %d\n", OFFSETOF(st_3, sh1));
printf("offset of d2 in st_3 = %d\n", OFFSETOF(st_3, d2));
printf("offset of ch3 in st_3 = %d\n", OFFSETOF(st_3, ch3));
printf("offset of i4 in st_3 = %d\n", OFFSETOF(st_3, i4));
打印:
sizeof st_3=16
offset of sh1 in st_3 = 0
offset of d2 in st_3 = 2
offset of ch3 in st_3 = 10
offset of i4 in st_3 = 12
对比一下:
struct st_3_2
{
short sh1;
double d2;
char ch3;
int i4;
};
printf("sizeof st_3_2=%d\n", sizeof(st_3_2));
printf("offset of sh1 in st_3_2 = %d\n", OFFSETOF(st_3_2, sh1));
printf("offset of d2 in st_3_2 = %d\n", OFFSETOF(st_3_2, d2));
printf("offset of ch3 in st_3_2 = %d\n", OFFSETOF(st_3_2, ch3));
printf("offset of i4 in st_3_2 = %d\n", OFFSETOF(st_3_2, i4));
打印:
sizeof st_3=24
offset of sh1 in st_3_2 = 0
offset of d2 in st_3_2 = 8
offset of ch3 in st_3_2 = 16
offset of i4 in st_3_2 = 20
(7)成员中有结构s,宽度按照s内部最宽元素与s的pack值中的最小值计算
struct st_4
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
printf("offset of ch0 in st_4 = %d\n", OFFSETOF(st_4, ch0));
printf("offset of _st3 in st_4 = %d\n", OFFSETOF(st_4, _st3));
printf("offset of ch1 in st_4 = %d\n", OFFSETOF(st_4, ch1));
printf("offset of _st3_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2));
printf("offset of _st0 in st_4 = %d\n", OFFSETOF(st_4, _st0));
printf("offset of _st3_2_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2_2));
printf("offset of sh in st_4 = %d\n", OFFSETOF(st_4, sh));
打印:
sizeof st_4=88
offset of ch0 in st_4 = 0
offset of _st3 in st_4 = 2
offset of ch1 in st_4 = 18
offset of _st3_2 in st_4 = 24
offset of _st0 in st_4 = 48
offset of _st3_2_2 in st_4 = 56
offset of sh in st_4 = 80
对比一下:
#pragma pack(push)
#pragma pack(4)
struct st_4_2
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
#pragma pack(pop)
printf("offset of ch0 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch0));
printf("offset of _st3 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3));
printf("offset of ch1 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch1));
printf("offset of _st3_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2));
printf("offset of _st0 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st0));
printf("offset of _st3_2_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2_2));
printf("offset of sh in st_4_2 = %d\n", OFFSETOF(st_4_2, sh));
打印:
sizeof st_4_2=76
offset of ch0 in st_4_2 = 0
offset of _st3 in st_4_2 = 2
offset of ch1 in st_4_2 = 18
offset of _st3_2 in st_4_2 = 20
offset of _st0 in st_4_2 = 44
offset of _st3_2_2 in st_4_2 = 48
offset of sh in st_4_2 = 72
///
// 测试程序
///
#include <stdio.h>
//本程序演示对齐规则
struct st_0
{
char ch[2];
char chx;
};
struct st_0_2 {};
struct st_1
{
char ch1;
short sh2;
int i3;
};
#pragma pack(push)
#pragma pack(2)
struct st_3
{
short sh1;
double d2;
char ch3;
int i4;
};
#pragma pack(pop)
struct st_3_2
{
short sh1;
double d2;
char ch3;
int i4;
};
struct st_4
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
#pragma pack(push)
#pragma pack(4)
struct st_4_2
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
#pragma pack(pop)
#define OFFSETOF(STRUCT,MEMBER) ((unsigned int)(&(((STRUCT*)0)->MEMBER)))
int main(int argc, char* argv[])
{
st_1 _st1;
st_0 _st0;
st_1 _st1_2;
printf("sizeof st_0=%d\n", sizeof(st_0));
printf("sizeof st_1=%d\n", sizeof(st_1));
printf("sizeof st_0_2=%d\n", sizeof(st_0_2));
putchar('\n');
printf("address of _st1=%u %u/sizeof(_st1) =%.2f\n", &_st1, &_st1, (float)(((unsigned int)(&_st1)) / (sizeof(_st1) * 1.0f)));
printf("address of _st0=%u %u/sizeof(_st0) =%.2f\n", &_st0, &_st0, (float)(((unsigned int)(&_st0)) / (sizeof(_st0) * 1.0f)));
printf("address of _st1_2=%u %u/sizeof(_st1_2)=%.2f\n", &_st1_2, &_st1_2, (float)(((unsigned int)(&_st1_2)) / (sizeof(_st1_2) * 1.0f)));
putchar('\n');
printf("offset of ch1 in st_1 = %d\n", OFFSETOF(st_1, ch1));
printf("offset of sh2 in st_1 = %d\n", OFFSETOF(st_1, sh2));
printf("offset of i3 in st_1 = %d\n", OFFSETOF(st_1, i3));
putchar('\n');
printf("sizeof st_3=%d\n", sizeof(st_3));
printf("offset of sh1 in st_3 = %d\n", OFFSETOF(st_3, sh1));
printf("offset of d2 in st_3 = %d\n", OFFSETOF(st_3, d2));
printf("offset of ch3 in st_3 = %d\n", OFFSETOF(st_3, ch3));
printf("offset of i4 in st_3 = %d\n", OFFSETOF(st_3, i4));
putchar('\n');
printf("sizeof st_3_2=%d\n", sizeof(st_3_2));
printf("offset of sh1 in st_3_2 = %d\n", OFFSETOF(st_3_2, sh1));
printf("offset of d2 in st_3_2 = %d\n", OFFSETOF(st_3_2, d2));
printf("offset of ch3 in st_3_2 = %d\n", OFFSETOF(st_3_2, ch3));
printf("offset of i4 in st_3_2 = %d\n", OFFSETOF(st_3_2, i4));
putchar('\n');
printf("sizeof st_4=%d\n", sizeof(st_4));
printf("offset of ch0 in st_4 = %d\n", OFFSETOF(st_4, ch0));
printf("offset of _st3 in st_4 = %d\n", OFFSETOF(st_4, _st3));
printf("offset of ch1 in st_4 = %d\n", OFFSETOF(st_4, ch1));
printf("offset of _st3_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2));
printf("offset of _st0 in st_4 = %d\n", OFFSETOF(st_4, _st0));
printf("offset of _st3_2_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2_2));
printf("offset of sh in st_4 = %d\n", OFFSETOF(st_4, sh));
putchar('\n');
printf("sizeof st_4_2=%d\n", sizeof(st_4_2));
printf("offset of ch0 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch0));
printf("offset of _st3 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3));
printf("offset of ch1 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch1));
printf("offset of _st3_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2));
printf("offset of _st0 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st0));
printf("offset of _st3_2_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2_2));
printf("offset of sh in st_4_2 = %d\n", OFFSETOF(st_4_2, sh));
getchar();
return 0;
}
(1)struct总长度是其最宽的元素的长度的整数倍
struct st_1
{
char ch1;
short sh2;
int i3;//最宽 size=4
};
printf("sizeof st_1=%d\n",sizeof(st_1));
打印:
sizeof st_1=8
(2)成员中有数组,宽度按照单个元素计算
struct st_0
{
char ch[2];//数组宽度2 单个元素宽度1
char chx;
};
printf("sizeof st_0=%d\n",sizeof(st_0));
打印:
sizeof st_0=3
(3)空结构体的大小不为0,而是1
struct st_0_2 {};
printf("sizeof st_0_2=%d\n",sizeof(st_0_2));
打印:
sizeof st_0_2=1
(4)结构体变量的首地址能够被其最宽基本类型成员的大小所整除
//继续使用(2)中的st_0
//继续使用(1)中的st_1
st_1 _st1;
st_0 _st0;
st_1 _st1_2;
printf("address of _st1=%u %u/sizeof(_st1) =%.2f\n", &_st1, &_st1, (float)(((unsigned int)(&_st1)) / (sizeof(_st1) * 1.0f)));
printf("address of _st0=%u %u/sizeof(_st0) =%.2f\n", &_st0, &_st0, (float)(((unsigned int)(&_st0)) / (sizeof(_st0) * 1.0f)));
printf("address of _st1_2=%u %u/sizeof(_st1_2)=%.2f\n", &_st1_2, &_st1_2, (float)(((unsigned int)(&_st1_2)) / (sizeof(_st1_2) * 1.0f)));
打印:
address of _st1=3865312 3865312/sizeof(_st1) =483164.00 //能够整除最长元素int
address of _st0=3865300 3865300/sizeof(_st0) =1288433.38 //没有整除,但可被1整除说明按照char宽度对齐地址
address of _st1_2=3865284 3865284/sizeof(_st1_2)=483160.50 //没有整除整个结构宽度,但整除int的宽度
(5)每个元素起始于元素宽度的整倍数
//继续使用(1)中的st_1
#define OFFSETOF(STRUCT,MEMBER) ((unsigned int)(&(((STRUCT*)0)->MEMBER)))
printf("offset of ch1 in st_1 = %d\n", OFFSETOF(st_1, ch1));
printf("offset of sh2 in st_1 = %d\n", OFFSETOF(st_1, sh2));
printf("offset of i3 in st_1 = %d\n", OFFSETOF(st_1, i3));
打印:
offset of ch1 in st_1 = 0
offset of sh2 in st_1 = 2
offset of i3 in st_1 = 4
(6)#pack值为1、2、4、8、16,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准
#pragma pack(push)
#pragma pack(2)
struct st_3
{
short sh1;
double d2;
char ch3;
int i4;
};
#pragma pack(pop)
printf("sizeof st_3=%d\n", sizeof(st_3));
printf("offset of sh1 in st_3 = %d\n", OFFSETOF(st_3, sh1));
printf("offset of d2 in st_3 = %d\n", OFFSETOF(st_3, d2));
printf("offset of ch3 in st_3 = %d\n", OFFSETOF(st_3, ch3));
printf("offset of i4 in st_3 = %d\n", OFFSETOF(st_3, i4));
打印:
sizeof st_3=16
offset of sh1 in st_3 = 0
offset of d2 in st_3 = 2
offset of ch3 in st_3 = 10
offset of i4 in st_3 = 12
对比一下:
struct st_3_2
{
short sh1;
double d2;
char ch3;
int i4;
};
printf("sizeof st_3_2=%d\n", sizeof(st_3_2));
printf("offset of sh1 in st_3_2 = %d\n", OFFSETOF(st_3_2, sh1));
printf("offset of d2 in st_3_2 = %d\n", OFFSETOF(st_3_2, d2));
printf("offset of ch3 in st_3_2 = %d\n", OFFSETOF(st_3_2, ch3));
printf("offset of i4 in st_3_2 = %d\n", OFFSETOF(st_3_2, i4));
打印:
sizeof st_3=24
offset of sh1 in st_3_2 = 0
offset of d2 in st_3_2 = 8
offset of ch3 in st_3_2 = 16
offset of i4 in st_3_2 = 20
(7)成员中有结构s,宽度按照s内部最宽元素与s的pack值中的最小值计算
struct st_4
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
printf("offset of ch0 in st_4 = %d\n", OFFSETOF(st_4, ch0));
printf("offset of _st3 in st_4 = %d\n", OFFSETOF(st_4, _st3));
printf("offset of ch1 in st_4 = %d\n", OFFSETOF(st_4, ch1));
printf("offset of _st3_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2));
printf("offset of _st0 in st_4 = %d\n", OFFSETOF(st_4, _st0));
printf("offset of _st3_2_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2_2));
printf("offset of sh in st_4 = %d\n", OFFSETOF(st_4, sh));
打印:
sizeof st_4=88
offset of ch0 in st_4 = 0
offset of _st3 in st_4 = 2
offset of ch1 in st_4 = 18
offset of _st3_2 in st_4 = 24
offset of _st0 in st_4 = 48
offset of _st3_2_2 in st_4 = 56
offset of sh in st_4 = 80
对比一下:
#pragma pack(push)
#pragma pack(4)
struct st_4_2
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
#pragma pack(pop)
printf("offset of ch0 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch0));
printf("offset of _st3 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3));
printf("offset of ch1 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch1));
printf("offset of _st3_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2));
printf("offset of _st0 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st0));
printf("offset of _st3_2_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2_2));
printf("offset of sh in st_4_2 = %d\n", OFFSETOF(st_4_2, sh));
打印:
sizeof st_4_2=76
offset of ch0 in st_4_2 = 0
offset of _st3 in st_4_2 = 2
offset of ch1 in st_4_2 = 18
offset of _st3_2 in st_4_2 = 20
offset of _st0 in st_4_2 = 44
offset of _st3_2_2 in st_4_2 = 48
offset of sh in st_4_2 = 72
///
// 测试程序
///
#include <stdio.h>
//本程序演示对齐规则
struct st_0
{
char ch[2];
char chx;
};
struct st_0_2 {};
struct st_1
{
char ch1;
short sh2;
int i3;
};
#pragma pack(push)
#pragma pack(2)
struct st_3
{
short sh1;
double d2;
char ch3;
int i4;
};
#pragma pack(pop)
struct st_3_2
{
short sh1;
double d2;
char ch3;
int i4;
};
struct st_4
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
#pragma pack(push)
#pragma pack(4)
struct st_4_2
{
char ch0;
st_3 _st3;
char ch1;
st_3_2 _st3_2;
st_0 _st0;
st_3_2 _st3_2_2;
short sh[2];
};
#pragma pack(pop)
#define OFFSETOF(STRUCT,MEMBER) ((unsigned int)(&(((STRUCT*)0)->MEMBER)))
int main(int argc, char* argv[])
{
st_1 _st1;
st_0 _st0;
st_1 _st1_2;
printf("sizeof st_0=%d\n", sizeof(st_0));
printf("sizeof st_1=%d\n", sizeof(st_1));
printf("sizeof st_0_2=%d\n", sizeof(st_0_2));
putchar('\n');
printf("address of _st1=%u %u/sizeof(_st1) =%.2f\n", &_st1, &_st1, (float)(((unsigned int)(&_st1)) / (sizeof(_st1) * 1.0f)));
printf("address of _st0=%u %u/sizeof(_st0) =%.2f\n", &_st0, &_st0, (float)(((unsigned int)(&_st0)) / (sizeof(_st0) * 1.0f)));
printf("address of _st1_2=%u %u/sizeof(_st1_2)=%.2f\n", &_st1_2, &_st1_2, (float)(((unsigned int)(&_st1_2)) / (sizeof(_st1_2) * 1.0f)));
putchar('\n');
printf("offset of ch1 in st_1 = %d\n", OFFSETOF(st_1, ch1));
printf("offset of sh2 in st_1 = %d\n", OFFSETOF(st_1, sh2));
printf("offset of i3 in st_1 = %d\n", OFFSETOF(st_1, i3));
putchar('\n');
printf("sizeof st_3=%d\n", sizeof(st_3));
printf("offset of sh1 in st_3 = %d\n", OFFSETOF(st_3, sh1));
printf("offset of d2 in st_3 = %d\n", OFFSETOF(st_3, d2));
printf("offset of ch3 in st_3 = %d\n", OFFSETOF(st_3, ch3));
printf("offset of i4 in st_3 = %d\n", OFFSETOF(st_3, i4));
putchar('\n');
printf("sizeof st_3_2=%d\n", sizeof(st_3_2));
printf("offset of sh1 in st_3_2 = %d\n", OFFSETOF(st_3_2, sh1));
printf("offset of d2 in st_3_2 = %d\n", OFFSETOF(st_3_2, d2));
printf("offset of ch3 in st_3_2 = %d\n", OFFSETOF(st_3_2, ch3));
printf("offset of i4 in st_3_2 = %d\n", OFFSETOF(st_3_2, i4));
putchar('\n');
printf("sizeof st_4=%d\n", sizeof(st_4));
printf("offset of ch0 in st_4 = %d\n", OFFSETOF(st_4, ch0));
printf("offset of _st3 in st_4 = %d\n", OFFSETOF(st_4, _st3));
printf("offset of ch1 in st_4 = %d\n", OFFSETOF(st_4, ch1));
printf("offset of _st3_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2));
printf("offset of _st0 in st_4 = %d\n", OFFSETOF(st_4, _st0));
printf("offset of _st3_2_2 in st_4 = %d\n", OFFSETOF(st_4, _st3_2_2));
printf("offset of sh in st_4 = %d\n", OFFSETOF(st_4, sh));
putchar('\n');
printf("sizeof st_4_2=%d\n", sizeof(st_4_2));
printf("offset of ch0 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch0));
printf("offset of _st3 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3));
printf("offset of ch1 in st_4_2 = %d\n", OFFSETOF(st_4_2, ch1));
printf("offset of _st3_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2));
printf("offset of _st0 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st0));
printf("offset of _st3_2_2 in st_4_2 = %d\n", OFFSETOF(st_4_2, _st3_2_2));
printf("offset of sh in st_4_2 = %d\n", OFFSETOF(st_4_2, sh));
getchar();
return 0;
}