自定义类型变量的大小(数据对齐)

这个其实是老师留的作业,自己就研究了一把,结果发现和老师讲的方法不一样,但是思路还是具体一样的,我觉得还是一个知识点,只要能够说清楚,明白,那是最好的。

一说到这种大小问题,其实就不简简单单的是语言的问题,更重要的是还和编译器,和操作系统都密不可分。

首先说一说在windows下的结构体的大小吧:

首先为了提高效率,提高存储系统的性能,每一个数据所分配的地址与该数据的类型都有密不可分的联系,例如:&y 0x001dfc0c int * &ch   0x001dfc1b "" char *      &sh  0x001dfc00 short *这是我在vs2008中定义的一些变量,并且取了地址,转化为十进制之后地址分别为  1,965,068   1,965,083   1,965,056  第一个地址可以sizeof(int)整除,同理后两个也是,意思就是说 编译器给一个变量分配的地址一定能被它(变量)所占的字节数(大小)所整除,这就给我们接下来的重点奠定了基础了。

直接来一个代码看看,

struct su{
char ch; //0x0   若这行数据占1B那么int的地址就是0x1,不能被4整除,所以就占4个字节
int y;  //0x4
short sh;//0x8若这行占2B 那么下一个结构(不一定为结构变量)的地址应为0x10,不能满足被4整除
};

在vs中大小是12,按照不知道数据对齐的人的理解char应该是一个字节,int是4个,而short是2个,那么总的大小应该是7.

结构体是不同类数据的聚合,就像数组一样,他们占据的是一整块内存,那么好,咱们刚才也说了地址与数据自身类型的关系,那么对于上述的结构体ch占有一个字节,那么 y 能不能紧跟其后呢,显然是不行,因为它要满足   一个变量分配的地址一定能被它(变量)所占的字节数(大小)所整除   的条件,所以很明显,对于一个ch  来说,其实他后面还要在浪费3B的空间才能让y放入,y可以放入之后,看看sh    2B  那么是可以被接着放的,这样的话结果应该是10,可是编译器告诉我们是12,这是为什么呢,原因是每个结构体又有一个最宽数据(名字我给忘了,sorry),也就是说,一个结构体的大小还要能被最宽数据大小整除,在此例中,最宽的应该是int那么整个结构的大小就是10+2(在short后在补上两个字节),这样做的原因是,如果来一个这样结构的数组,那么得能够保证数组元素之间实现无缝聚合。

struct su{
char ch;//1+7
double dou;//8
int y;//4
int i;//4
int j;//4+4
};

 产生一个32B变量。但是在linux中,却不这样做,它要满足能被8B以上的数据按4B对齐。

#pragma pack(4)
struct su{
char ch;
double dou;
char y;
int i;
int j;
};
#pragma pack()

在vs中可以用上述方法改变最大数据对齐方式,也就是将超过4B的数据全都按照4B的方法对齐,结果是24。

#pragma pack(4)
struct su{
char ch;//1
char dou;//1
char y;//1+1
int i;//4
int j;//4
};
#pragma pack()

结果为12B。

先写这么多,有时间了将会写一下结构中有其他自定义类型的情况。

可能有不是那么准确的地方,体谅。







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值