此内容由EEWORLD论坛网友tiankai001原创,如需转载或用于商业用途需征得作者同意并注明出处
记得刚刚学会用C语言编写单片机程序的时候,由于程序中同一事件中需要用到多个数据,为方便起见,就将这些数据定义为一个结构体。因为事先没有很好的规划数据,并且对结构体的使用也是一知半解,就对结构体中的数据没有很好的规划,于是就出现了类似这样的结构体。
- struct StuData
- {
- char u1;
- int u2;
- Char u3
- Char u4;
- }StuD;
复制代码
结果在程序中调用这个结构体时,尤其是把这个结构体整体赋值给一个数组的时候,总是会出现赋值后的数组中第一个数组元素的值等于u1,但是第二个数组元素的值却不是int b的低字节或者高字节,当时对C语言不是很熟悉,所以对这个问题百思不得其解。
但是问题总要解决,于是就查找资料,最终找到问题的根源所在:在定义结构体的时候,要千万注意结构体的对齐规则。
那么结构体的对齐规则究竟是什么呢?
原则一结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始(以结构体变量首地址为0计算)。
比如此例,首先系统会将字符型变量a存入第0个字节(相对地址,指内存开辟的首地址);然后在存放整形变量b时,会以4个字节为单位进行存储,由于第一个四字节模块已有数据,因此它会存入第二个四字节模块,也就是存入到4~8字节;同理,存放双精度实型变量c时,由于其宽度为8,其存放时会以8个字节为单位存储,也就是会找到第一个空的且是8的整数倍的位置开始存储,此例中,此例中,由于头一个8字节模块已被占用,所以将c存入第二个8字节模块。
原则二在经过第一原则分析后,检查计算出的存储单元是否为所有元素中最宽的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍。
掌握了这两个原则,就能够分析所有数据存储对齐问题了
由于结构体所占空间与其内部元素的类型有关,而且与不同类型元素的排列有关,因此在定义结构体时,在元素类型及数量确定之后,我们还应该注意一下其内部元素的定义顺序。
那么,上面的那个结构体的正确定义方法应该是什么呢?我们可以自己在计算机上试试。