標籤:har include print inf 先來 src 說明 str 對齊
資料對齊
結構體之間的對齊是有很多種方法的,也是根據你所用的系統位元有關。下面都是以32位系統來講的,32位系統一般以字對齊,字就是系統位元,32位系統則是32位對齊,也就是4位元組(int型)對齊。
講程式前我還是先來說下為什麼要對齊(面試時也問了下這個問題)?說到底還是為了效率,為了cpu的工作效率。舉個例子:一個unsigned short (2位元組)類型的變數以下面兩種方式儲存。
非對齊儲存:CPU在讀取(說明下32位系統有32根地址線,所以CPU每次都讀取32位也就是4個位元組的資料)資料時,首先讀取0x00地址到0x03地址上的4個位元組資料,然後分析只有0x03地址上的資料才是CPU想要的,所以保留這個位元組的資料。接著讀取0x04地址到0x07地址內的4個位元組資料,分析可的只有0x04地址上的資料才是CPU想要的,所以保留下。最後把在0x03地址上讀取到的資料和在0x04地址上讀取到的資料合起來才能得到CPU想要讀取的那個unsigned short型資料。
對齊儲存:CPU直接讀取0x00地址到0x03地址上的4個位元組資料,然後分析,保留0x02地址和0x03地址上的2個位元組資料,就可以得到CPU想要讀取的那個unsigned short型資料。
這樣一比較我想大家都能看出來對齊儲存對CPU工作效率來說是非常關鍵的。所以系統預設都設定字對齊,以方便CPU工作。如果是非字對齊(人為的用強轉為地址賦值)有的編譯器沒問題,但有的編譯器會直接報錯。
下面來看程式,如果當結構體成員中有char型,int型,short型等資料類型時,系統是怎麼分配儲存地址的。
#include<stdio.h>typedef struct test{char C1;int I1;short ST1;char C2;int I2;char C3;short ST2;}T;int main(){T t;printf("C1: %p\n", &t.C1);printf("I1: %p\n", &t.I1);printf("ST1: %p\n", &t.ST1);printf("C2: %p\n", &t.C2);printf("I2: %p\n", &t.I2);printf("C3: %p\n", &t.C3);printf("ST2: %p\n", &t.ST2);printf("sizeof(T):%d\n", sizeof(T));return 0;}
【C語言】資料對其(記憶體對齊)