c#中的結構
假設有乙個類:
class dimensions
public double length;
public double width;
定義了乙個類,
它只儲存某一項的長度和寬度
.嘉定編寫乙個布置家居的程式
,讓人們試著在計算機上重新布置家具
,並儲存每件家具的維度
.使欄位變為共有字段
,就會違背變成規則
,但我們實際上並不需要類的全部功能
.現在只有兩個數字
,把他們當做一堆來處理
,要比單個處理方便一些
.既不需要很多方法
,也不需要從類中繼承
,也不希望
.net
執行庫在堆中遇到麻煩和效能問題
,值儲存兩個
double
型別的資料即可.
為此,只需要修改**
,使用關鍵字
struct
代替class,
定義乙個結構而不是類
struct dimensions
public double length;
public double width;
為結構定義函式與味蕾定義函式完全相同.
struct dimensions
public double length;
public double width;
public dimensions(double length, double width)
this.length = length;
this.width = width;
public double diagonal
getreturn math.sqrt(length * length + width * width);
結構是值型別,
不是引用型別
.他們儲存在棧中或儲存為內聯
,其生存期的限制與簡單的資料型別一樣.
結構不支援繼承.
對於結構建構函式的工作方式有一些區別.
尤其是編譯器總是提供乙個無引數的預設建構函式
,他是不允許替換的.
使用結構,
可以指定字段如何在記憶體中的布局.
因為結構實際上是把資料項組合在一起,
有時大多數或者全部的字段都宣告為
public.
嚴格來說
,這是違背
.net
**的規則的,根據
microsoft,字段(
除了const
字段之外
)應該總是私有的
,並由共有屬性封裝
.但是對於簡單的結構
,共有字段還是可以接受的.
結構是值型別
雖然結構是值型別,
但是在語法上常常可以把他們當做類來處理.例如
,上面的
dimension
類的定義中
,可以編寫下面的**:
dimensions point = new dimensions();
point.lenth=3;
point.width=6;
注意,因為結構是值型別,所以
new運算子與類和其他引用型別的工作方式不同
.new
運算子並不分配隊中的記憶體
,而是只呼叫相應的建構函式
,根據傳送給他的引數
,初始化所有的字段
.對於結構
,可以編寫下面**:
dimensions point;
point.length=3;
point.width=6;
如果dimensions
是乙個類
,就會產生錯誤,因為
point
包含乙個為初始化的引用
----
不知想任何地方的乙個位址
,所以不能給其欄位設定值
.但是對於結構
,變數宣告實際上是維護整個結構在棧中分配空間
,所以就可以為他賦值了.
但是如果這樣:
dimensions point;
double d=point.length;
編譯器就會產生乙個錯誤,
原因是使用了未初始化的變數.
結構遵循其他資料型別都遵循的規則:
在使用前所有的元素都必須進行初始化
.在結構上呼叫
new運算子
,或者給所有的字段分別賦值
,結構就完全初始化了
.如果結構定義為類的成員字段
,在初始化包含的物件時
,該結構會自動初始化為0.
結構是會影響效能的值型別.
結構不失為繼承設計的.
這意味著
:他不能從乙個結構中繼承
.唯一的例外是對應的結構(和
c#中的其他型別一樣
)最終派生於類
system.object.
因此結構可以訪問
system.object
的方法.
在結構中
,甚至可以重寫
system.objetc
中的方法
----
如重寫tostring()方法.
結構的繼承鏈是
:每個結構派生自
system.valuetype
類,system.valuetype
類又派生自
system.object.valuetype
並沒有給
object
新增任何新成員
,但提供了一些更適合結構的額實現方式.注意
,不能為結構提供其他類
:每個結構都派生自
valuetype.
結構的建構函式
為結構定義建構函式的方式與為類定義建構函式的方式相同,
但不允許定義無引數的建構函式
.禁止在
c#的結構內使用無引數的建構函式.
前面說過,
預設建構函式把數值字段都初始化為
0,把引用型別字段初始化為
null,
且總是隱式的給出
,及時提供了其他帶引數的建構函式
,也是如此
,提供欄位的初始值也不鞥呢繞過預設建構函式.
例如:
struct dimensions
public double length=1;
public double width=2;
會出現錯誤,
結構中不能有例項字段初始值設定項
,如果是類就不會出現這個錯誤.
另外,可以向類那樣為結構提供
close()
或dispose()方法.
struct總結
:struct
型別適於表示
point
、rectangle
和color
等輕量物件。為結構定義預設(無引數)建構函式是錯誤的。
在結構體中初始化例項欄位也是錯誤的。
只能通過兩種方式初始化結構成員:一是使用引數化建構函式,二是在宣告結構後分別訪問成員。
對於任何私有成員或以其他方式設定為不可訪問的成員,只能在建構函式中進行初始化。
如果使用
new運算子建立結構物件,則會建立該結構物件,並呼叫適當的建構函式。
與類不同,結構的例項化可以不使用
new
運算子。
在此情況下不存在構造函式呼叫,因而可以提高分配效率。
但是,在初始化所有字段之前,欄位將保持未賦值狀態且物件不可用。
當結構包含引用型別作為成員時,必須顯式呼叫該成員的預設建構函式,否則該成員將保持未賦值狀態且該結構不可用。
(這將導致編譯器錯誤
cs0171。)
對於結構,不像類那樣存在繼承。
乙個結構不能從另乙個結構或類繼承,而且不能作為乙個類的基。
但是,結構從基類
object
繼承。結構可實現介面,其方式同類完全一樣。
無法使用struct
關鍵字宣告類。
在 c#
中,類與結構在語義上是不同的。
結構是值型別,而類是引用型別。
C 高階程式設計第八天 Main 函式
main 方法.c 程式是以 main 開始執行的 這個方法必須是類或結構的靜態方法 並且其返回型別必須是 int或者 void.雖然顯示指定public 修飾符很常見 但是我們也可以把該方法標記為 private,也可以執行.main 方法只能有乙個 如果有多個就會出現錯誤.如果非得寫兩個main...
C 學習(十八)C 中的volatile
volatile的本意是 易變的 volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改,比如作業系統 硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的 就不再進行優化,從而可以提供對特殊位址的穩定訪問。當要求使用volatile 宣告的變數...
C 高階 C 中的陣列退化
在c 中,陣列永遠不會按值傳遞。它是傳遞第0個元素的指標 即首位址 例如,如下宣告 void putvalues int 10 被編譯器視為 void putvalues int 陣列的長度與陣列的宣告無關。因此,下列三個宣告是等價的 void putvalues int void putvalue...