研究問題:
- 結構體、聯合體基本概念?
- 結構體&&聯合體爲什麼搞基?
- 關於結構體、聯合體中涉及到的內存對齊?
要點:
結構體是數據項的集合,每條結構體項由其類型和名稱制定。
聯合體是所有成員共用一個空間;使用的是同一個起始地址。這樣,後來的數據就會覆蓋先前的數據。所有聯合體union的大小隻配置一個足夠大來容納聯合體成員中最大長度數據成員類型的大小;
來自 http://blog.sina.com.cn/s/blog_b0a23f620102vl07.html
- 結構體struct、聯合體union區別?
1.在存儲多個成員信息時,編譯器會自動給struct第個成員分配存儲空間,struct 可以存儲多個成員信息,而Union每個成員會用同一個存儲空間,只能存儲最後一個成員的信息。
2.都是由多個不同的數據類型成員組成,但在任何同一時刻,Union只存放了一個被先選中的成員,而結構體的所有成員都存在。
3.對於Union的不同成員賦值,將會對其他成員重寫,原來成員的值就不存在了,而對於struct 的不同成員賦值 是互不影響的。
注:在很多地方需要對結構體的成員變量進行修改。只是部分成員變量,那麼就不能用聯合體Union,因爲Union的所有成員變量佔一個內存。eg:在鏈表中對個別數值域進行賦值就必須用struct.
來自 https://www.cnblogs.com/webber1992/p/5950199.html
結構體的內存對其原則
原則1、數據成員對齊規則:結構(struct或聯合union)的數據成員,第一個數據成員放在offset爲0的地方,以後每個數據成員存儲的起始位置要從該成員大小的整數倍開始(比如int在32位機爲4字節,則要從4的整數倍地址開始存儲)。原則2、結構體作爲成員:如果一個結構裏有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍地址開始存儲。(struct a裏存有struct b,b裏有char,int,double等元素,那b應該從8的整數倍開始存儲。)
原則3、收尾工作:結構體的總大小,也就是sizeof的結果,必須是其內部最大成員的整數倍,不足的要補齊。
1) 結構體變量的地址一定夠被其最寬基本類型成員的大小所整除
如:
Struct stud
{
Int a;
Char b;
Double c
}stu;
其大小必須被c的類型double整除。故其大小爲4+1+8=13;但實際上是16.
2)結構體每一個成員相對應結構體首地址的偏移量offset都是成員大小的整數倍,如果不夠,必須在成員名上,補充相應的位置
計算的基本規則:
結構體元素是按照一個一個順序放入內存的,但是並不是緊密的排列。從結構圖的首地址開始,每一個元素都放到內存中時,都會認爲內存給自己分配了空間,異常元素存放的位置一定是自己寬度的整數倍。首地址一般是爲int或double型
經過原則1之後,檢查計算出的存儲單元是否是所在結構體元素最寬元素類型長度的整數倍,如果是,則結束,如果不是則補齊爲整數倍。
PS:只要是在32位系統中,指針變量都佔4個字節。無論其指針的類型是什麼。
union u
{
double a;
int b;
};
union u2
{
char a[13];
int b;
};
union u3
{
char a[13];
char b;
};
cout<<sizeof(u)<<endl; // 8
cout<<sizeof(u2)<<endl; // 16
cout<<sizeof(u3)<<endl; // 13
都知道union的大小取決於它所有的成員中,佔用空間最大的一個成員的大小。所以對於u來說,大小就是最大的double類型成員a了,所以sizeof(u)=sizeof(double)=8。但是對於u2和u3,最大的空間都是char[13]類型的數組,爲什麼u3的大小是13,而u2是16呢?關鍵在於u2中的成員int b。由於int類型成員的存在,使u2的對齊方式變成4,也就是說,u2的大小必須在4的對界上,所以佔用的空間變成了16(最接近13的對界)。
來自 https://www.cnblogs.com/webber1992/p/5950199.html
- 聯合體的內存對其原則
union的長度取決於其中的長度最大的那個成員變量的長度。即union中成員變量是重疊擺放的,其開始地址相同。
其實union(共用體)的各個成員是以同一個地址開始存放的,每一個時刻只可以存儲一個成員,這樣就要求它在分配內存單元時候要滿足兩點:
1.一般而言,共用體類型實際佔用存儲空間爲其最長的成員所佔的存儲空間;
2.若是該最長的存儲空間對其他成員的元類型(如果是數組,取其類型的數據長度,例int a[5]爲4)不滿足整除關係,該最大空間自動延伸;
union mm{
char a;//元長度1
int b[5];//元長度4
double c;//元長度8
int d[3];
};
sizeof(mm)=24=8(因爲[1+4]<8取8)+8+8(因爲3<8取8)
來自 http://blog.csdn.net/u010479322/article/details/51137907