在设计不同CPU下的通信协议时,或者编写硬件驱动程序时寄存器的结构这两个地方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐,以免不同的编译器生成的代码不一样.
如何查找与字节对齐方面的问题
如果出现对齐或者赋值问题首先查看
1.编译器设置的对齐值
2.看这种体系本身是否支持非对齐访问
3.如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作。
1、充分考虑四字节对齐,可以节省存储空间
typedef struct tagAAA{
char name[10];
long sno;
char sex;
float score[4];
}AAA;
typedef struct tagBBB{
char name[10];
char sex;
long sno;
float score[4];
}BBB;
在VC下,调试,可以很容易看出来,AAA占的存储空间为36,BBB占的存储空间为32。原因很简单,在四字节对齐的情况下,按四个字节为单位分配存储空间,如果不足,会自动补充,本次分配不足以存放下面的变量时,会重新分配空间。
AAA:
|name[0]|name[1]|name[2]|name[3]|
------------------------------------
|name[4]|name[5]|name[6]|name[7]|
------------------------------------
|name[8]|name[9]| | |
----------由于剩下的两个字节不足以存放sno(long占四个字节),所以重新分配
------------------------------------
| sno |
----------long变量占四个字节,32bits
------------------------------------
|sex | 自动填充 |
----------剩余三个字节的空间,不足以重放一个float变量,因此重新分配
------------------------------------
| score[0] |
------------------------------------
| .......... |
------------------------------------
| score[3] |
------------------------------------
由此可以轻易的计算出,AAA占36个字节,同理,很容易计算出BBB占32个字节空间。
2、字节对其的情况下,可以更高效的访问
假设一个结构体的数据如下存储:
-----------------------------------------------------
| 12 | 34 | 56 | 78 | -----------(A)
-----------------------------------------------------
-----------------------------------------------------
| XX | YY | 12 | 34 | -----------(B)
-----------------------------------------------------
| 56 | 78 | XX | YY |
在A情况下,一次性读取数据成功,但是,在B情况下,需要读取数据两次,由此,可看出效率的差异。
一般情况下,字节对齐遵从系统字节数与要求的对齐字节数相比,最小原则,即:假设要求按八字节对齐,但是系统为32位系统,则按照4字节对齐。在四字节对齐时,局部会按照2字节对齐,如:
struct tagAAA
{
char a;
short b;
char c;
}AAA;
该结构体占据的空间为8字节而不是4字节,原因就是:
-----------------------------------
| a | | b |
-----------------------------------
| c | |
而不是:
------------------------------------
| a | b | c |
------------------------------------
其原因就是局部会以2字节对齐。