關於C 中的結構

2021-06-20 21:55:06 字數 3317 閱讀 5796

在深入.net平台與c#程式設計的教學中,第二章中講到關於結構的概念及應用,學員感覺結構與類之間的區分有點困難,現在將c#中的結構相關的知識點整理了一下,希望能對你的學習帶來幫助。

結構是一種值型別,並且不需要堆分配。結構的例項化可以不使用new運算子。如果宣告乙個10000個point物件組成的陣列,為了引用每個物件,則需分配更多記憶體;這種情況下,使用結構可以節約資源。

結構是使用struct關鍵字定義的,與類相似,都表示可以包含資料成員和函式成員的資料結構。

一般情況下,我們很少使用結構,而且很多人也並不建議使用結構,但作為.net framework 一般型別系統中的乙個基本架構,我們還是有必要了解一下的。

結構的特徵:

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

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

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

struct

temp

\ty =\tname = ", x,y, sname);}}

class

program

",temp2.x);//

輸出結果值為5,主要原因是結構是值型別}}

此時temp2.x值為5是因為,將temp1賦值給temp2是對值進行複製,因此,temp2不會受到temp1.x賦值得改變而改變。

但如果temp是類,這時temp1和temp2裡的x引用的是同乙個位址,則temp2.x的值會輸出20。

4、結構的裝箱與拆箱我們知道,乙個類型別的值可以轉換為object型別或由該類實現的介面型別,這只需在編譯時把對應的引用當作另乙個型別處理即可。

與此類似,乙個object型別的值或者介面型別的值也可以被轉換回類型別而不必更改相應的引用。當然,在這種情況下,需要進行執行時型別檢查。由於結構不是引用型別,上述操作對結構型別是以不同的方式實現的。

當結構型別的值被轉換為object型別或由該結構實現的介面型別時,就會執行一次裝箱操作。

反之,當 object型別的值或介面型別的值被轉換回結構型別時,會執行一次拆箱操作。

與對類型別進行的相同操作相比,主要區別在於:

裝箱操作會把相關的結構值複製為已被裝箱的例項,而拆箱則會從已被裝箱的例項中複製出乙個結構值。

因此,在裝箱或拆箱操作後,對「箱」外的結構進行的更改不會影響已被裝箱的結構。

class

program

\to =", i,o);

}//結果為:i = 20     o =  10 

5、結構與建構函式我們知道結構不能使用預設的建構函式,只能使用帶引數的建構函式,當定義帶引數的建構函式時,一定要完成結構所有欄位的初始化,如果沒有完成所有欄位的初始化,編譯時會發生錯誤。結構可以使用靜態建構函式嗎?

可以,結構的靜態建構函式與類的靜態建構函式所遵循的規則大體相同。

6、結構的靜態建構函式何時將觸發呢?結構的例項成員被引用,結構的靜態成員被引用,結構顯示宣告的建構函式被呼叫。但是建立結構型別的預設值不會觸發靜態建構函式。

7、為什麼結構不能自定義無引數的建構函式?

結構型別的建構函式與類的建構函式類似,用來初始化結構的成員變數,但是struct不能包含顯式預設建構函式,因為編譯器將自動提供乙個建構函式,此建構函式將結構中的每個字段初始化為預設值表中顯示的預設值。

然而,只有當結構用new例項化時,才會呼叫此預設建構函式。對值型別呼叫預設建構函式不是必需的。

struct

temp

public

void method(){}}

class

program

結果為:kyaccp

8、結構與繼承:

乙個結構宣告可以指定實現的介面列表,但是不能指定基類。

由於結構不支援類與結構的繼承,所以結構成員的宣告可訪問性不能是protected或protectedinternal。結構中的函式成員不能是abstract或 virtual,因而override修飾符只適用於重寫從system.valuetype繼承的方法。

9、 為在設計程式語言時將結構設計成無繼承性?

其實類的繼承是有相當的成本的 ——由於繼承性,每個類需要用額外的資料空間來儲存「繼承圖」來表示類的傳承歷史,通俗地說來就是我們人類的家族家譜,裡面儲存著我們的祖宗十八代,只有這樣我們才知道我們從**來的,而家譜肯定是需要額外的空間來存放的。

我們不要覺得這個存放「繼承圖」的空間很小,如果我們的程式需要用10000個點(point)來存放遊戲中的人物形體資料的話,在乙個場景中又有n個人,這個記憶體開銷可不是小數目了。所以我們可以通過將點(point)申明成 struct而不是class來節約記憶體空間。

inte***ce

itemp

struct

temp : itemp

\ty =", x,y);}}

class

program

// 結果為:x = 5      y = 10 

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

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

什麼時候使用結構?

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

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

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

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

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

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

C 中的結構(結構體)

結構是可以包含資料成員和函式成員的資料結構,這一點和類一樣 下面我們講一下結構與類不同的地方 1.結構體是值型別,無需進行堆分配,類是引用型別 2.結構型別的變數直接儲存資料結構,而類型別的變數儲存對動態分配的物件的引用 3.類支援繼承,結構體不支援繼承 4.關鍵字簡單說下,類是class,結構體是...

關於c 中的dllimport

msdn中對dllimportattribute的解釋是這樣的 可將該屬性應用於方法。dllimportattribute 屬性提供對從非託管 dll 匯出的函式進行呼叫所必需的資訊。作為最低要求,必須提供包含入口點的 dll 的名稱。並給了乙個示例 dllimport kernel32.dll e...

關於C 中的Timer

關於c 中timer類 在c 裡關於定時器類就有3個 1.定義在system.windows.forms裡 2.定義在system.threading.timer類裡 3.定義在system.timers.timer類裡 例 使用system.timers.timer類 system.timers....