收藏, 以防忘了
来源:互联网 发布:mac橘红色适合什么肤色 编辑:程序博客网 时间:2024/04/30 09:46
在c语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。
例如,下面的结构各成员空间分配情况:
struct test
{
char x1;
short x2;
float x3;
char x4;
};
结构的第一个成员x1,其偏移地址为0,占据了第1个字节。第二个成员x2为short类型,其起始地址必须2字节对界,因此,编译器在x2和x1之间填充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上,在它们前面不需要额外的填充字节。在test结构中,成员x3要求4字节对界,是该结构所有成员中要求的最大对界单元,因而test结构的自然对界条件为4字节,编译器在成员x4后面填充了3个空字节。整个结构所占据空间为12字节。更改c编译器的缺省字节对齐方式
在缺省情况下,c编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:
· 使用伪指令#pragma pack (n),c编译器将按照n个字节对齐。
· 使用伪指令#pragma pack (),取消自定义字节对齐方式。
另外,还有如下的一种方式:
· __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
· __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。
以上的n = 1, 2, 4, 8, 16... 第一种方式较为常见。
应用实例
在网络协议编程中,经常会处理不同协议的数据报文。一种方法是通过指针偏移的方法来得到各种信息,但这样做不仅编程复杂,而且一旦协议有变化,程序修改起来也比较麻烦。在了解了编译器对结构空间的分配原则之后,我们完全可以利用这一特性定义自己的协议结构,通过访问结构的成员来获取各种信息。这样做,不仅简化了编程,而且即使协议发生变化,我们也只需修改协议结构的定义即可,其它程序无需修改,省时省力。下面以tcp协议首部为例,说明如何定义协议结构。其协议结构定义如下:
#pragma pack(1) // 按照1字节方式进行对齐
struct tcpheader
{
short srcport; // 16位源端口号
short dstport; // 16位目的端口号
int serialno; // 32位序列号
int ackno; // 32位确认号
unsigned char haderlen : 4; // 4位首部长度
unsigned char reserved1 : 4; // 保留6位中的4位
unsigned char reserved2 : 2; // 保留6位中的2位
unsigned char urg : 1;
unsigned char ack : 1;
unsigned char psh : 1;
unsigned char rst : 1;
unsigned char syn : 1;
unsigned char fin : 1;
short windowsize; // 16位窗口大小
short tcpchksum; // 16位tcp检验和
short urgentpointer; // 16位紧急指针
};
#pragma pack() // 取消1字节对齐方式
- 收藏, 以防忘了
- 先写下以防忘了
- listview显示不同布局的一个坑(记一下,以防后面又忘了)
- 好不容易把HP的ACHI搞定了,也是看的别人的,先转帖出来,以防忘了!
- HQL函数、操作符(以防忘记了)
- 最近做了一个Mqtt消息推送,和大家分享分享心得,以防以后搞忘了,新人第一次写博客,大神勿喷。
- 音乐播放器挂了,浏览器网页播放代码语句【以防忘记】
- 浑浑噩噩眼看快毕业了,记录一下自己的代码以防以后会忘记把
- 开始收藏了
- 好文,,,收藏了
- 收藏搬家了
- 设计模式收藏了
- 觉得有用就收藏了!
- SQL collate 先收藏了
- 网上Copy的,收藏了
- 各类存储器介绍 收藏了
- 回答的很好,收藏了
- 挺好的文章收藏了
- 64位系统 inline api hook之我见
- 制作文件系统映像和相关参数设置
- 微软平台程序员的悲哀
- 汇编语言源程序组成
- CSS 之 float 实现多个层横排
- 收藏, 以防忘了
- ldr与adr的区别 (相对地址 和 绝对地址)
- 利用Java-JACOB操作WORD文档2
- 软件开发管理十大工作任务
- 编译错误
- 小组活动学习
- 贪吃蛇(java版本)留作回忆【共三份文件:1、 TestSnake.java 2、Snake. java 3、Food.java】
- 好的习惯----程序员成长之路(from老大邮件)
- 虚拟机内存复用技术的比较(主要针对XEN系统)