結構體的定義宣告 記憶體對齊

2021-08-11 18:00:25 字數 1993 閱讀 8771

什麼是結構體?結構體怎麼進行定義宣告?

結構體是一種資料結構,可以被宣告為陣列、指標和變數,結構體內部通常是由多個相同或不同型別的變數組成,舉幾個例子來說明理解它的定義宣告,如下:

1.

struct student;

結構體中包含指向自己的指標:

struct

complex;

結構體間互相包含時,需要對其中之一進行不完整宣告:

struct b; 

struct a ;

struct b ;

在程式中正確合適地使用結構體會方便很多;

接下來說一說計算結構體大小的問題,這就必須得掌握結構體的記憶體對齊規則,看下面:

1.首先,為什麼會存在記憶體對齊問題呢?

在我看到的資料上是這樣的解釋:

a)平台原因(移植原因): 不是所有的硬體平台都能訪問任意位址上的任意資料的;某些硬體平台只能在某些位址處取某些特定型別的資料,否則丟擲硬體異常;

b)效能原因: 資料結構(尤其是棧)應該盡可能地在自然邊界上對齊,原因在於為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問,而對齊的記憶體訪問僅需要一次訪問。

2.看看記憶體對齊的規則是怎樣描述的:

第一種理解如下:

a) 第乙個成員在與結構體變數偏移量為0的位址處;

b) 其他成員變數要對齊到某個數字(對齊數)的整數倍的位址處;

對齊數 = 編譯器預設的乙個對齊數與該成員大小的較小值;

vs對齊數是8,linux是4

c)結構體總大小為最大對齊數(每個成員變數除了第乙個成員都有乙個對齊數)的整數倍。

如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。

(2)第二種:

a) 結構體第乙個成員的位址和結構體的首位址相同;

b) 結構體每個成員位址相對於結構體首位址的偏移量是該成員大小的整數倍,如果不是則編譯器會在成員之間新增填充位元組;

c) 結構體總的大小要是其成員中最大size的整數倍,如果不是編譯器會在其末尾新增填充位元組。

現在舉幾個例子看看結構體大小是怎麼計算的(在vs下):

struct s1 ;
第乙個成員『char c1』,大小是1位元組,偏移量是0;

『int i』大小是4位元組,偏移量為4,所以在其之前填充3位元組;『

『char c2』大小1位元組,不需要填充。

1+3+4+1=9,因為結構體大小要是成員中的最大位元組的整數倍,所以結構體大小為12

struct s2 ;
『char c1』是1位元組;

『char c2』是1位元組;

『int i』是4位元組,偏移量要為其整數倍,所以其之前填充2位元組;

1+1+2+4=8,恰好為int型別的整數倍,所以結構體大小為8

struct s3;
『char ch』為1位元組;

『int a』是4位元組,偏移量為4,則填充3位元組;

『double b 『是8位元組,因為其之前是int型別,所以不需要填充位元組了;

『char c1』是1位元組;

1+3+4+8+1=17,不是double型別大小的整數倍,所以在最後填充7個位元組,17+7=24,結構體大小為24

struct s4;

經過上面4個例子的計算,可知道即使兩個結構體內部成員相同,但如果它們的先後順序不一樣,結構體的大小也是會有區別的;而且計算時一定要注意偏移量是否計算正確了;

那麼在設計結構體的時候,我們既要滿足對齊,又要節省空間,可以通過讓結構體內部占用空間小的成員盡量放在一起。

結構體對齊(記憶體對齊

有的時候,在腦海中停頓了很久的 顯而易見 的東西,其實根本上就是錯誤的。就拿下面的問題來看 structt 使用sizeof t 將得到什麼樣的答案呢?要是以前,想都不用想,在32位機中,int是4個位元組,char是1個位元組,所以t一共是5個位元組。實踐出真知,在vc6中測試了下,答案確實8個位...

記憶體對齊 結構體對齊

現在已知32位機器上各種資料型別的長度如下 char 1 有符號無符號同 short 2 有符號無符號同 int 4 有符號無符號同 long 4 有符號無符號同 float 4 double 8 重要規則 1,複雜型別中各個成員按照它們被宣告的順序在記憶體中順序儲存,第乙個成員的位址和整個型別的位...

結構體的記憶體對齊

原則一 結構體中元素是按照定義順序乙個乙個放到記憶體中去的,但並不是緊密排列的。從結構體儲存的首位址開始,每乙個元素放置到記憶體中時,它都會認為記憶體是以它自己的大小來劃分的,因此元素放置的位置一定會在自己寬度的整數倍上開始 以結構體變數首位址為0計算 原則二 在經過第一原則分析後,檢查計算出的儲存...