在設計不同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字節對齊。