爲了高速處理數據,現代處理器的設計引入了對齊的概念。所謂對齊就是保證數據在內存中存儲時地址變化按照必定的規律,這樣就能夠保證每次cpu取一樣長度的數據進行運算,所以能夠提升計算機的運行速度。spa
下面的程序演示內存中的對齊:設計
#include <stdio.h> struct test{ char ch; short s; int i; }; int main(void) { struct test var; printf("size of var : %d\n", sizeof(var)); return 0; }
運行結果爲:code
該結構體擁有一個char型、一個short型和一個int型成員變量,所佔用的字節數應該是7個,可是結果倒是8個字節,這是由於編譯器採用了默認的對齊方式。內存
基本數據類型的自身對齊值爲其數據類型的大小。編譯器
默認的指定對齊值爲成員中自身對齊值最大的那個值。io
使用下面語句能夠指定對齊值value:編譯
#progma pack (value) /*指定按value字節對齊*/ struct A { int a; }; #progma pack () /*取消指定對齊,恢復缺省對齊*/
其成員中自身對齊值最大的那個值。class
自身對齊值和指定對齊值中較小的那個值。test
設結構體以下:變量
struct test{ char ch; int i; short s; };
假設test的起始地址爲0x0000,默認的指定對齊值爲4,因此:
當咱們指定對齊值爲2字節時,再分析上面的結構體
#pragma pack(2) //指定按2字節對齊 struct test1{ char ch; int i; short s; }; #pragma pack() //取消指定對齊,恢復缺省對齊
假設test1的起始地址爲0x0000,指定對齊值爲2,因此:
1.程序以下:
#include <stdio.h> #pragma pack(8) struct example1 { short a; long b; }; struct example2 { char c; struct example1 struct1; short e; }; #pragma pack() int main(int argc, char* argv[]) { struct example2 struct2; struct example1 e1; printf("size of example1 : %d\n", sizeof(e1)); printf("size of example2 : %d\n", sizeof(struct2)); printf("%d\n", (unsigned long int)(&struct2.struct1) - (unsigned long int)(&struct2)); return 0; }
程序的輸出結果是什麼?
答案是:
分析這個程序:
對於example1:
對於example2:
對於(unsigned long int)(&struct2.struct1) - (unsigned long int)(&struct2):
由於在example2中struct1以前有個char類型的成員變量,因爲struct1的對齊值爲8因此char變量須要填充7個字節,所以結果爲8。
2.第二個程序:
#include <stdio.h>\ union A { int a[5]; char b; double c; }; struct B { int n; union A a; char c[10]; }; int main(void) { union A a1; struct B b; printf("size of union : %d\n", sizeof(a1)); printf("size of struct : %d\n", sizeof(b)); return 0; }
A和B的大小爲:
分析程序:
因爲union是共享內存的,首先看每一個成員所佔大小:
union A { int a[5]; //20字節 char b; //1字節 double c; //8字節 };
A中各變量默認內存對齊方式,必須以最長的double 8字節對齊,因此A的大小爲24字節(20+4)。
結構體B中:
struct B { int n; //4字節 union A a; //24字節 char c[10]; //10字節 };
因爲A是8字節對齊的,因此B中的int與char[]也須要8字節對齊,因此大小爲:8+24+16 = 48。