結構體元素順序與結構體的大小

來源:互聯網
上載者:User

說明:暑假中看書想到的一點東西,因當時沒有電腦,無法驗證,所以到學校後驗證一下才發。
     
   先看一個例子,有三個結構體的定義如下:
struct  a    
{
 bool    b1;
 bool    b2;
 int     i1;
 int     i2;
 int     i3;
};

struct  b
{
 int     i1;
 int     i2;
 int     i3;
 bool    b1;
 bool    b2;
};
  
struct  c

{
 int       ii1;
 bool      bb1;
 int       ii2;
 bool      bb2;
 int       ii3;
   
};
   對於上面定義的兩個結構體,考慮下面的兩個問題:
   1.三個結構體大小的理論值和實際值各是多少?
   2.三個結構體所佔的記憶體空間大小(實際所佔非理論值)是否相同?為什嗎?
對於1我們很容易得出結果,三個結構體大小的理論值都是14。因為在32位的系統中int的大小是4byte,bool的大小為1byte,而結構體的大小為各元素所佔大小的和,所以理論值為14,至於實際大小我們也可以很容易的得到:
#include<iostream>
using namespace std;
int main()
{
 cout<<"a's size:/t"<<sizeof(a)<<endl;
        cout<<"b's size:/t"<<sizeof(b)<<endl;
        cout<<"c's size:/t"<<sizeof(c)<<endl;
        return 0;
}
可以得到大小依次是:16,16,20,這樣第一個問題就解決了,第二個問題也解決了一部分。至於問什麼這樣呢,這與微機系統的記憶體組織有關。
    在微機系統中,儲存空間是分體的,具體的說16位的系統分為2個儲存體,32位的系統分為4儲存體。因為儲存空間是分體的,在儲存資料時應考慮資料存放區的位置盡量以偶地址(16位)或4的倍數(32位)開始,也就是所謂的“對準”。如果在16位的系統中存放一個字(2byte)的資料時,如果以奇地址開始,那麼在讀一個字的時候就需要2個刻度,而以偶地址開始儲存是指需要一個刻度。因此所謂的對準也就是用空間換取時間的一種方法。我們可以猜測在32位的編譯器中,便量存放的地址應該是以4的地址的倍數開始的,這是可以驗證的:
#include<iostream>
using namespace std;

#include<iostream>
using namespace std;

int main()
{
 int a;
 bool b1,b2;
 float c;
 double d;

 cout<<"variable/t"<<"Address"<<endl;
 cout<<"a/t/t"<<&a<<endl;
 cout<<"b1/t/t"<<&b1<<endl;
 cout<<"b2/t/t"<<&b2<<endl;
 cout<<"c/t/t"<<&c<<endl;
 cout<<"d/t/t"<<&d<<endl;
 
 return 0;
}
輸出結果如下:
variable        Address
a               0012FF7C
b1              0012FF78
b2              0012FF74
c               0012FF70
d               0012FF68
下面看一下上面定義的結構體的各成員的地址分配:
int  main()
{
 
 a  aa;
 b  bb;
 c  cc;
 cout<<"int size:/t"<<sizeof(int)<<"byte"<<endl;
 cout<<"bool size:/t"<<sizeof(bool)<<"byte"<<endl;
 
 cout<<"size  a :"<<sizeof(a)<<endl;
 cout<<"Address of element in aa:"<<endl;
 cout<<"b1's  address/t/t"<<&(aa.b1)<<endl;
 cout<<"b2's  address/t/t"<<&(aa.b2)<<endl;
 cout<<"i1's  address/t/t"<<&(aa.i1)<<endl;
 cout<<"i2's  address/t/t"<<&(aa.i2)<<endl;
 cout<<"i3's  address/t/t"<<&(aa.i3)<<endl;

 cout<<"size  b :"<<sizeof(b)<<endl;
 cout<<"Address of element in bb:"<<endl;
 cout<<"i1's  address/t/t"<<&(bb.i1)<<endl;
 cout<<"i2's  address/t/t"<<&(bb.i2)<<endl;
 cout<<"i3's  address/t/t"<<&(bb.i3)<<endl;
 cout<<"b1's  address/t/t"<<&(bb.b1)<<endl;
 cout<<"b2's  address/t/t"<<&(bb.b2)<<endl;
 
 cout<<"size b:"<<sizeof(c)<<endl;
 cout<<"Address of element in cc:"<<endl;    
 cout<<"i1's  address/t/t"<<&(cc.i1)<<endl;
 cout<<"b1's  address/t/t"<<&(cc.b1)<<endl;
 cout<<"i2's  address/t/t"<<&(cc.i2)<<endl;
 cout<<"b2's  address/t/t"<<&(cc.b2)<<endl;
 cout<<"i3's  address/t/t"<<&(cc.i3)<<endl;

 return 0;
}
運行結果:
int size:       4byte
bool size:      1byte
size  a :16
Address of element in aa:
b1's  address           0012FF70
b2's  address           0012FF71
i1's  address           0012FF74
i2's  address           0012FF78
i3's  address           0012FF7C
size  b :16
Address of element in bb:
i1's  address           0012FF60
i2's  address           0012FF64
i3's  address           0012FF68
b1's  address           0012FF6C
b2's  address           0012FF6D
size b:20
Address of element in cc:
i1's  address           0012FF4C
b1's  address           0012FF50
i2's  address           0012FF54
b2's  address           0012FF58
i3's  address           0012FF5C
通過結果就可以說明為什麼結構體的大小因元素的位置不一樣而大小不一樣了。因為編譯器在儲存是採用了對齊(對準),所以大小有所不同。結構體a中兩個布爾變數b2的地址並不是4的倍數,這並不矛盾,因為在這裡把結構體看作是像內部類型一樣的類型,其內部元素對外是作為一個整體的。
    因此,在聲明一個結構體時,盡量按一頂的順序(從大到小或從小到大)來排列各元素,這樣就可以減少其所佔的空間,不過現在記憶體空間已不再是著重考慮的問題,因為也可以從便於閱讀的方面去排列。

  PS. 以上是我關於結構體大小的一點的一點想法,不知正確與否,歡迎批評指正。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.