1. 程式人生 > 實用技巧 >C#:值型別變數和引用型別變數在記憶體中的儲存方式

C#:值型別變數和引用型別變數在記憶體中的儲存方式

值型別變數:以變數名所對應的記憶體地址為起點,以其資料型別所要求的儲存空間為長度的一塊記憶體區域。

計算機儲存和讀取資料的最小單位是位元組、再每個位元組編上唯一的編號後大概便是下面的樣子。

我們常說的記憶體地址,就是指資料在記憶體中的記憶體編號。按照編號查詢某個資料在記憶體單元中的位置,稱為定址。

對於作業系統,他保留了一段記憶體區域以供作業系統來使用,其它程式不允許使用這個記憶體。----在上圖中用 黃色標記。

對於程式來說,他們使用記憶體就是剩下的區域。

值型別變數在記憶體中是如何儲存的:

例子1:byte a; a=100;為例。

分析:

1、看到byte時,我們知道變數a佔據一個位元組的記憶體空間。

2、計算機去尋找記憶體中,哪裡有空閒的儲存空間,則從此處分配記憶體空間。

3、a=100,100用二進位制補碼錶示時:01100 0100,儲存到分配給a的空餘空間中。

所以,最終 10000007 就是變數a的記憶體地址。

例子2:以 sbyte b;b=-100;為例:

1、sbyte 是有符號的整型,最高位表示符號位,取值範圍從-128~+127;

2、我們知道計算機中儲存的數是以二進位制補碼的形式存放的,-100的補碼:10011100

3、計算機會為變數b尋找到一個空餘記憶體,並分配一位元組的空間,並將10011100填充到這塊空間中

所以,變數b在記憶體中的儲存形式便是上圖,b變數的記憶體地址是 10000010

例子3:以ushort c=1000;為例:

1、ushort 兩個佔據兩個位元組的儲存空間,表示無符號整數

2、1000的二進位制形式位:0000 0011 1110 1000

3、對於超過一個自己空間大小的變數,資料在記憶體中儲存的規則:高高低低原則--即:高位放在記憶體地址編號大的位置、低位放在記憶體地址編號小的位置。

所以,ushort型別變數c的記憶體地址是 1000 0016。

例子4:對於值型別資料,他們可以呼叫Convert.Tostring()方法,來快速求出二進位制表示形式,解決了我們求類似-1000的補碼比較慢的問題。

short c = -1000;
string s = Convert.ToString(c, 2);
Console.WriteLine(s);

執行結果:1111 1100 0001 1000

引用型別變數:引用型別變數裡面儲存的是例項的記憶體地址。

下面來看一下引用型別變數和引用型別例項在記憶體中的對應關係。

比如:在Main()方法中有下面一段程式碼:Student student;student=new Student();已知Student型別中有兩個成員 int型別ID、short型別score;

1、當程式解析到 Student student時,判斷到student是引用型別的變數,那麼分配記憶體的方式和值型別完全不同。

2、值型別變數是按照,變數的實際大小分配空間的,而引用型別變數執行分配四個自己內訓空間,並且初始值都設定為0。

3、當解析到student=new Student()時,分兩步操作,

  • 第一步:相應new Student(),在堆記憶體中根據成員型別和個數分配相應大小的空間

  • 第二部:將物件在堆記憶體中的其實記憶體地址的值轉換成二進位制值,賦值給引用型別變數

經計算,30000009的二進位制值是:00000001110010011100001110001001 按照高高低低原則,給student變數所佔的記憶體區域賦值後。

4、最終student變數儲存的便是Student型別例項的記憶體地址,我們可以說,引用型別變數通過例項的地址指向了堆中了一個例項。

總結:

1、區域性變數 比如stundent、a、b、c等,都是在Mian方法中的 他們是在Stack上面分配記憶體的

2、例項變數 比如Student型別中的 ID、Score欄位等,他們是在Heap上面分配記憶體的

以上是對引用型別變數和值型別變數在記憶體中的儲存方式的總結,記錄下來,以便以後查閱。