c 之結構體

2021-07-05 18:54:13 字數 2939 閱讀 9679

結構是使用 struct 關鍵字定義的,與類相似,都表示可以包含資料成員和函式成員的資料結構。 一般情況下,我們很少使用結構,而且很多人也並不建議使用結構,但作為.net framework 一般型別系統中的乙個基本架構,還是有必要了解一下的。

結構的特徵: 結構是一種值型別,並且不需要堆分配。 結構的例項化可以不使用 new 運算子。

在結構宣告中,除非欄位被宣告為 const 或 static,否則無法初始化。 結構型別永遠不是抽象的,並且始終是隱式密封的,因此在結構宣告中不允許使用abstract和sealed修飾符。

結構不能宣告預設建構函式(沒有引數的建構函式)或析構函式,但可以宣告帶引數的建構函式。 結構可以實現介面,但不能從另乙個結構或類繼承,而且不能作為乙個類的基,所有結構都直接繼承自system.valuetype,後者繼承自 system.object。 結構在賦值時進行複製。 將結構賦值給新變數時,將複製所有資料,並且對新副本所做的任何修改不會更改原始副本的資料。 在使用值型別的集合(如 dictionary)時,請務必記住這一點。 結構型別的變數直接包含了該結構的資料,而類型別的變數所包含的只是對相應資料的乙個引用(被引用的資料稱為「物件」)。但是結構仍可以通過ref和out引數引用方式傳遞給函式成員。 結構可用作可以為 null 的型別,因而可向其賦 null 值。

struct

a,y=,str=

", x, y,str);}}

class

program

",a1.x);

console.read();

}}

結果為:x=1,y=2,str=            a1.x=1 此時a1.x值為1是因為,將a賦值給a1是對值進行複製,因此,a1不會受到a.x賦值得改變而改變。

但如果a是類,這時a和a1裡的x引用的是同乙個位址,則a1.x的值會輸出10。

結構的裝箱與拆箱

我們知道,乙個類型別的值可以轉換為 object 型別或由該類實現的介面型別,這只需在編譯時把對應的引用當作另乙個型別處理即可。 與此類似,乙個object 型別的值或者介面型別的值也可以被轉換回類型別而不必更改相應的引用。當然,在這種情況下,需要進行執行時型別檢查。 由於結構不是引用型別,上述操作對結構型別是以不同的方式實現的。 當結構型別的值被轉換為object 型別或由該結構實現的介面型別時,就會執行一次裝箱操作。 反之,當 object 型別的值或介面型別的值被轉換回結構型別時,會執行一次拆箱操作。 與對類型別進行的相同操作相比,主要區別在於: 裝箱操作會把相關的結構值複製為已被裝箱的例項,而拆箱則會從已被裝箱的例項中複製出乙個結構值。 因此,在裝箱或拆箱操作後,對「箱」外的結構進行的更改不會影響已被裝箱的結構。

struct

program

,o="

,i,o);

console.read();}}

//結果為:i=123,o=1

結構與建構函式

我們知道結構不能使用預設的建構函式,只能使用帶引數的建構函式,當定義帶引數的建構函式時,一定要完成結構所有欄位的初始化,如果沒有完成所有欄位的初始化,編譯時會發生錯誤­。 結構可以使用靜態建構函式嗎? 可以,結構的靜態建構函式與類的靜態建構函式所遵循的規則大體相同。 結構的靜態建構函式何時將觸發呢? 結構的例項成員被引用,結構的靜態成員被引用,結構顯示宣告的建構函式被呼叫。 但是建立結構型別的預設值不會觸發靜態建構函式。為什麼結構不能自定義無引數的建構函式? 結構型別的建構函式與類的建構函式類似,用來初始化結構的成員變數,但是struct不能包含顯式預設建構函式, 因為編譯器將自動提供乙個建構函式,此建構函式將結構中的每個字段初始化為預設值表中顯示的預設值。 然而,只有當結構用new例項化時,才會呼叫此預設建構函式。對值型別呼叫預設建構函式不是必需的。

struct

apublic

void

fun()

}class

program

}結果為:i am a.

結構與繼承:

乙個結構宣告可以指定實現的介面列表,但是不能指定基類。 由於結構不支援類與結構的繼承,所以結構成員的宣告可訪問性不能是 protected 或 protected internal。 結構中的函式成員不能是 abstract 或 virtual,因而 override 修飾符只適用於重寫從 system.valuetype 繼承的方法。 為在設計程式語言時將結構設計成無繼承性?­ 其實類的繼承是有相當的成本的 ——由於繼承性,每個類需要用額外的資料空間來儲存「繼承圖」來表示類的傳承歷史, 通俗地說來就是我們人類的家族家譜,裡面儲存著我們的祖宗十八代,只有這樣我們才知道我們從**來的,而家譜肯定是需要額外的空間來存放的。 大家不要覺得這個存放「繼承圖」的空間很小,如果我們的程式需要用10000個點(point)來存放遊戲中的人物形體資料的話, 在乙個場景中又有n個人,這個記憶體開銷可不是小數目了。所以我們可以通過將點(point)申明成 struct而不是class來節約記憶體空間。

inte***ce

itest

struct

a:itest

,y="

, x, y);}}

class

program}//

結果為:x=1,y=2

什麼情況下結構的例項化可以不使用new?

當結構中沒有引數時,結構的例項化可以不使用new;

當結構中有引數時,必須對結構中所有引數進行初始化後,才能不使用new對結構進行例項化。

什麼時候使用結構?

結構體適合一些小型資料結構,這些資料結構包含的資料以建立結構後不修改的資料為主;

例如:struct型別適於表示point、rectangle和color等輕量物件。

儘管可以將乙個點表示為類,但在某些情況下,使用結構更有效。

如果宣告乙個10000個point物件組成的陣列,為了引用每個物件,則需分配更多記憶體;這種情況下,使用結構可以節約資源。­

定義的時候不會用到物件導向的一些特性;

結構體在不發生裝箱拆箱的情況下效能比類型別是高很多的.

C 之結構體

structtype.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std struct student int main student p stu 定義乙個指向結構體student的指標 cout stu.num endl ...

c 之結構體

include using namespace std include 結構體 屬於使用者自定義的資料型別,允許使用者儲存不同的資料型別 自定義資料型別,一些型別集合組成的乙個型別 語法 struct 型別名稱 1.建立學生資料型別 學生包括 姓名,年齡,分數 struct student s3 2...

c語言結構體之結構體巢狀

注意 1結構體內部再次定義乙個結構體 但是沒有建立結構體的例項 也就是說再次定義的結構體內部的變數會被當做母結構體的成員變數 1 struct tianchao 2 11 12 13 void mainww 14 24 25 struct tianchao 26 b1 內部定義的第一種方式 35 s...