C 高階程式設計十八天 C 中的結構

2021-07-03 09:51:16 字數 4100 閱讀 2970

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...