union struct 對界問題

2021-08-31 12:54:01 字數 2113 閱讀 7639

8、從union的sizeof問題看cpu的對界

考慮下面問題:(預設對齊方式)

union u

; union u2

; union u3

; cout《都知道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的對界)。

結論:復合資料型別,如union,struct,class的對齊方式為成員中對齊方式最大的成員的對齊方式。

順便提一下cpu對界問題,32的c++採用8位對界來提高執行速度,所以編譯器會盡量把資料放在它的對界上以提高記憶體命中率。對界是可以更改的,使用#pragma pack(x)巨集可以改變編譯器的對界方式,預設是8。c++固有型別的對界取編譯器對界方式與自身大小中較小的乙個。例如,指定編譯器按2對界,int型別的大小是4,則int的對界為2和4中較小的2。在預設的對界方式下,因為幾乎所有的資料型別都不大於預設的對界方式8(除了long double),所以所有的固有型別的對界方式可以認為就是型別自身的大小。更改一下上面的程式:

#pragma pack(2)

union u2

; union u3

;#pragma pack(8)

cout《由於手動更改對界方式為2,所以int的對界也變成了2,u2的對界取成員中最大的對界,也是2了,所以此時sizeof(u2)=14。

結論:c++固有型別的對界取編譯器對界方式與自身大小中較小的乙個。

9、struct的sizeof問題

因為對齊問題使結構體的sizeof變得比較複雜,看下面的例子:(預設對齊方式下)

struct s1

; struct s2

; cout《同樣是兩個char型別,乙個int型別,乙個double型別,但是因為對界問題,導致他們的大小不同。計算結構體大小可以採用元素擺放法,我舉例子說明一下:首先,cpu判斷結構體的對界,根據上一節的結論,s1和s2的對界都取最大的元素型別,也就是double型別的對界8。然後開始擺放每個元素。

對於s1,首先把a放到8的對界,假定是0,此時下乙個空閒的位址是1,但是下乙個元素d是double型別,要放到8的對界上,離1最接近的位址是8了,所以d被放在了8,此時下乙個空閒位址變成了16,下乙個元素c的對界是4,16可以滿足,所以c放在了16,此時下乙個空閒位址變成了20,下乙個元素d需要對界1,也正好落在對界上,所以d放在了20,結構體在位址21處結束。由於s1的大小需要是8的倍數,所以21-23的空間被保留,s1的大小變成了24。

對於s2,首先把a放到8的對界,假定是0,此時下乙個空閒位址是1,下乙個元素的對界也是1,所以b擺放在1,下乙個空閒位址變成了2;下乙個元素c的對界是4,所以取離2最近的位址4擺放c,下乙個空閒位址變成了8,下乙個元素d的對界是8,所以d擺放在8,所有元素擺放完畢,結構體在15處結束,占用總空間為16,正好是8的倍數。

這裡有個陷阱,對於結構體中的結構體成員,不要認為它的對齊方式就是他的大小,看下面的例子:

struct s1

; struct s2

; struct s3

; struct s4

; cout所以,在自己定義結構體的時候,如果空間緊張的話,最好考慮對齊因素來排列結構體裡的元素。

10、不要讓double干擾你的位域

在結構體和類中,可以使用位域來規定某個成員所能占用的空間,所以使用位域能在一定程度上節省結構體占用的空間。不過考慮下面的**:

struct s1

; struct s2

; struct s3

; struct s4

; cout《可以看到,有double存在會干涉到位域(sizeof的演算法參考上一節),所以使用位域的的時候,最好把float型別和double型別放在程式的開始或者最後。

第一次寫東西,發現自己的表達能力太差了,知道的東西講不出來,講出來的東西別人也看不懂,呵呵。另外,c99標準的sizeof已經可以工作在執行時了,打算最近找個支援c99的編譯器研究一下。

逆序對問題

逆序對問題。給一列數a1 a2,an 求它的逆序對數,即有多少個有序對 i j 使得 i j 但ai aj n 可以高達106 由於 n 的數量級到了106 所以採用o n2 及以上的時間複雜度肯定會超時,所以必須選取o nlog 2n 及以下時間複雜度的演算法。逆序對的求解思路和歸併排序很像,嘗試...

最近對問題

有n個點,求距離最小的一對點。採用計算出所有點兩兩之間的距離,比較保留最小點距離就可以獲得。這樣時間複雜度為o n2 採用分治的思想來解決問題,可以發現這個問題的難點不在分,而在合併。以下對演算法步驟進行描述 1.找到一條線,將問題分解成兩個子集s1 s2 每個子集的大小為n 2 2.遞迴的發現s1...

最近對問題

設p1 x1,y1 p2 x2,y2 pn xn,yn 是平面n上n個點構成的集合s,最近對問你就是找出集合s中距離最近的點對。暴力法 在蠻力法實現最近點對問題中,將問題簡化 距離最近的點對可能多於一對,找出一對即可,另外只考慮二維平面中的情況。用距離公式即可求 分治法 分治法思想解決此問題時,首先...