c 值型別和引用型別詳析

2021-06-09 11:40:15 字數 2128 閱讀 4897

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 資料型別 值型別,引用型別 概念 值型別直接儲存其值,引用型別儲存對值的引用 這兩種型別儲存在記憶體的不同地方 值型別儲存在堆疊中,引用型別儲存在託管堆上。乙個引用型別的例子,如圖 上圖中,只有乙個user物件,u1和u2都指向包含該物件的記憶體位置 執行結果 在c 中,基本資料型別如bool和...

c 值型別和引用型別

今天我們來學習一下什麼是值型別和引用型別。1.值型別的值存在棧上,引用型別棧上存的是位址,值在堆上 2.將乙個值型別變數賦給另乙個值型別變數時,將複製包含的值。引用型別變數的賦值只複製對物件的引用,而不複製物件本身。3.裝箱是將值型別轉換為引用型別,拆箱是將引用型別轉換為值型別,利用裝箱和拆箱功能,...

C 值型別和引用型別

型別被分為兩種 值型別 整數,bool,struct 建構函式 char 字元 小數 引用型別 string 陣列 自定義的類,內建的類,物件.兩者在記憶體中的儲存方式 值型別 只需要一段單獨的記憶體,用於儲存實際的資料,單獨定義的時候放在棧中 引用型別 需要兩段記憶體 第一段儲存實際的資料,它總是...