结构体对齐规则总结与学习

结构体对齐规则(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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值