1. 程式人生 > >【C語言】數據對其(內存對齊)

【C語言】數據對其(內存對齊)

brush size return () def ont http 之間 sign

數據對齊

結構體之間的對齊是有很多種方法的,也是根據你所用的系統位數有關。下面都是以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語言】數據對其(內存對齊)