數據對齊與sizeof()

 面試題中 sizeof 的出現率還是很高的吧。常見的題,大家肯定也是知道答案的。但原因是否都瞭解呢?

 

下面就用VC 6來做一些這樣的題。

 

void main()
{
	int a=6;
	char str[10]="";
	char *p = str;
	double da;
	cout<<"size of b: "<<sizeof(a)<<endl;
	cout<<"size of str: "<<sizeof(str)<<endl;
	cout<<"size of p pointer: "<<sizeof(p)<<endl;
	cout<<"size of double: "<<sizeof(da)<<endl;}
    //結果:
	//4 因爲 a 是整型 其長度是 4位
	//10 這個不解釋
	//4 求的是指針的長度,指針也是 4 位
	//8 double 型的長度是 8
}


那結構體的長度怎麼求呢?

請看下面解釋:

 

struct s1
{
int a;
double b;
int c;
};

struct s2
{
int a;
int c;
double b;
};

sizeof(s1) = ?, sizeof(s2) = ?

結果:sizeof(s1) = 24,sizeof(s2) = 16

可見,雖然兩個結構體所含的元素相同,但因爲其中存放的元素類型順序不一樣,所佔字節也出現差異。這就是字節對齊原因。

 

字節對齊的計算。

 

結構體長度求法:
  
a.成員都相同時(或含數組且數組數據類型同結構體其他成員數據類型):
  結構體長度=成員數據類型長度×成員個數(各成員長度之和);
  結構體中數組長度=數組數據類型長度×數組元素個數;
  
b 成員不同且不含其它結構體時;
  (1).分析各個成員長度;
  (2).找出最大長度的成員長度M(結構體的長度一定是該成員的整數倍);
  (3).並按最大成員長度出現的位置將結構體分爲若干部分;
  (4).各個部分長度一次相加,求出大於該和的最小M的整數倍即爲該部分長度
  (5).將各個部分長度相加之和即爲結構體長度
  
c含有其他結構體時:
  (1).分析各個成員長度;
  (2).對是結構體的成員,其長度按b來分析,且不會隨着位置的變化而變化;
  (3).分析各個成員的長度(成員爲結構體的分析其成員長度),求出最大值;
  (4).若長度最大成員在爲結構體的成員中,則按結構體成員爲分界點分界;
  其他成員中有最大長度的成員,則該成員爲分界點;
  求出各段長度,求出大於該和的最小M的整數倍即爲該部分長度
  (5).將各個部分長度相加之和即爲結構體長度

 

舉例來說:
  1.struct test1

  { int a;
   int b[4];
  };
  sizeof(test1)=sizeof(int)+4*sizeof(int)=4+4*4=20;
  2. struct test2
  { char a;
   int b;
   double c;
   bool d;
  };
  分析:該結構體最大長度double型,長度是8,因此結構體長度分兩部分:
  第一部分是a、 b、 c的長度和,長度分別爲1,4,8,則該部分長度和爲13,取8的大於13的最小倍數爲16;
  第二部分爲d,長度爲1,取大於1的8的最小倍數爲8,
  兩部分和爲24,故sizeof(test2)=24;
  3. struct test3
  {
   char a;
   test2 bb;//見上題
   int cc;
  }
  分析:該結構體有三個成員,其中第二個bb是類型爲test2的結構體,長度爲24,且該結構體最大長度成員類型爲double型,以後成員中沒有double型,所以按bb分界爲兩部分:
  第一部分有a 、bb兩部分,a長度爲1,bb長度爲24,取8的大於25的最小倍數32;
  第二部分有cc,長度爲4,去8的大於4的最小倍數爲8;
  兩部分之和爲40,故sizeof(test3)=40;

 

下面結構體轉自:

http://apps.hi.baidu.com/share/detail/6503863

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章