C 值型別與引用型別 上

2021-07-03 05:16:45 字數 2140 閱讀 5416

原帖: 

1. 主要內容

型別的基本概念

值型別深入

引用型別深入

值型別與引用型別的比較及應用

2. 基本概念

c#中,變數是值還是引用僅取決於其資料型別。

c#的基本資料型別都以平台無關的方式來定義,c#的預定義型別並沒有內置於語言中,而是內置於.net framework中。.net使用通用型別系統(cts)定義了可以在中間語言(il)中使用的預定義資料型別,所有面向.net的語言都最終被編譯為 il,即編譯為基於cts型別的**,

通用型別的系統的功能:

例如,在c#中宣告乙個int變數時,宣告的實際上是cts中system.int32的乙個例項。這具有重要的意義:

int i; 

i = 1; 

string s; 

s = i.tostring();

clr 支援兩種型別:值型別和引用型別,

c#的所有值型別均隱式派生自system.valuetype:

bool型:bool(system.boolean的別名);

使用者定義的結構體(派生於system.valuetype)。

列舉:enum(派生於system.enum);

可空型別(派生於system.nullable泛型結構體,t?實際上是system.nullable的別名)。

c#有以下一些引用型別:

object(system.object的別名);

字串:string(system.string的別名)。

可以看出:

2.1記憶體深入

2.2.1 記憶體機制

private static class referencevsvalue

// value type (because of 'struct') 

private struct someval

public static void go()  

} 圖5-1       ****執行時的記憶體分配情況

someval是用struct來宣告的,而不是用常用的class,在c#中用struct宣告的是值型別,每個變數或者程式都有自己的堆疊,不同的變數不能公用乙個記憶體位址因此上圖中someref和someval一定占用了不同的堆疊,變數經過傳遞後,對v1變數改變時,顯然不會影響到v2的資料,可以看出,堆疊中的v1,v2包含其實際資料,而r1,r2則在堆疊中儲存了其實例資料的引用位址,實際的資料儲存在託管堆中,因此就有可能不同變數儲存了 同一位址的資料引用,當從乙個引用型別變數傳遞到另外乙個相同的引用型別變數時,傳遞的是引用位址而不是實際的資料,所以改變乙個變數的值會影響到另外乙個變數的值,值型別與引用型別在記憶體中的分配是決定其應用不同的根本原因,由此可以容易的解釋為什麼傳遞引數的時候,按值傳遞不會改變形參的值,而按位址傳遞會改變形參的值。

記憶體分配的幾點:

2.2.2巢狀型別

巢狀結構就是在值型別中巢狀定義了引用型別,或者在引用型別變數中巢狀定義了值型別

public class nestedvalueinref 

}                                      圖5-2 記憶體分配圖可以表示為:

引用型別巢狀在值型別時,記憶體的分配情況為:該引用型別將作為值型別的成員變數,堆疊上將儲存該成員的引用,而成員的實際資料還是儲存在託管堆中.

public struct nestedrefinvalue  }

圖5-3 記憶體分配圖可以表示為:

C 值型別與引用型別 上

c 中,變數是值還是引用僅取決於其資料型別。c 的基本資料型別都以平台無關的方式來定義。c 的預定義型別並沒有內置於語言中,而是內置於.net framework中。net使用通用型別系統 cts 定義了可以在中間語言 il 中使用的預定義資料型別,所有面向.net的語言都最終被編譯為il,即編譯為...

C 值型別與引用型別 上

1.主要內容 型別的基本概念 值型別深入 引用型別深入 值型別與引用型別的比較及應用 2.基本概念 c 中,變數是值還是引用僅取決於其資料型別。c 的基本資料型別都以平台無關的方式來定義,c 的預定義型別並沒有內置於語言中,而是內置於.net framework中。net使用通用型別系統 cts 定...

C 值型別與引用型別 上

1.主要內容 型別的基本概念 值型別深入 引用型別深入 值型別與引用型別的比較及應用 2.基本概念 c 中,變數是值還是引用僅取決於其資料型別。c 的基本資料型別都以平台無關的方式來定義,c 的預定義型別並沒有內置於語言中,而是內置於.net framework中。net使用通用型別系統 cts 定...