c语言字节对比,C语言字节对齐

结构体字节对齐的细节和具体编译器实现相关,但一般而言满足三个准则:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2) 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节{trailing padding}。

演示讲解

32位机器上各数据类型的长度为:char为1字节、short为2字节、int为4字节、long为4字节、float为4字节、double为8字节

afa31f7dba5228c4d6764e26d26a3397.png

阴影部分为内存填充

对于以上规则的说明如下:

第一条:编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能被该基本数据类型所整除的位置,作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。

第二条:为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员大小的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。

第三条:结构体总大小是包括填充字节,最后一个成员满足上面两条以外,还必须满足第三条,否则就必须在最后填充几个字节以达到本条要求。

示例代码

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*gcc/g++默认采用4字节对齐,当然可以指定对齐方式,如通过: #pragma pack (value)时的指定对齐值value。*/

/*OFFSET宏定义可取得指定结构体某成员在结构体内部的偏移*/

#define OFFSET(st, field) (size_t)&(((st*)0)->field)typedefstruct{chara;shortb;charc;intd;char e[3];

}T_Test;int main(void)

{

printf("Size = %d

a-%d, b-%d, c-%d, d-%d

e[0]-%d, e[1]-%d, e[2]-%d",sizeof(T_Test), OFFSET(T_Test, a), OFFSET(T_Test, b),

OFFSET(T_Test, c), OFFSET(T_Test, d), OFFSET(T_Test, e[0]),

OFFSET(T_Test, e[1]),OFFSET(T_Test, e[2]));return 0;

}

View Code

如何设置字节对齐方式

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

#pragma pack(push) //保存对齐状态

#pragma pack(1) //设置为1字节对齐typedefstruct{chara;shortb;charc;intd;char e[3];

}T_Test;#pragma pack(pop) //恢复对齐状态

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

#pragma pack(1) //设置为1字节对齐typedefstruct{chara;shortb;charc;intd;char e[3];

}T_Test;#pragma pack() //取消指定对齐,恢复缺省对齐

View Code

对于本地使用的数据结构,为提高内存访问效率,采用四字节对齐方式;同时为了减少内存的开销,合理安排结构体成员的位置,减少四字节对齐导致的成员之间的空隙,降低内存开销。

对于处理器之间的数据结构,需要保证消息长度不会因不同编译平台或处理器而导致消息结构体长度发生变化,使用一字节对齐方式对消息结构进行紧缩;为保证处理器之间的消息数据结构的内存访问效率,采用字节填充的方式自己对消息中成员进行四字节对齐。

数据结构的成员位置要兼顾成员之间的关系、数据访问效率和空间利用率。顺序安排原则是:四字节的放在最前面,两字节的紧接最后一个四字节成员,一字节紧接最后一个两字节成员,填充字节放在最后。

c6ccee8ce1b7a40250a47e65419f7516.png

6f7aa7614a5158f78b893f571005db98.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值