1. 程式人生 > >值型別和引用型別的區別

值型別和引用型別的區別

本文主要是討論棧和堆的含義,也就是討論C#的兩種類據型別值型別和引用型別;

  雖然我們在.net中的框架類庫中,大多是引用型別,但是我們程式設計師用得最多的還是值型別。

  引用型別如:string,Object,class等總是在從託管堆上分配的,C#中new操作符返回物件的記憶體地址--也就是指向物件資料的記憶體地址。

  以下是值型別與引用型別的表:

  

   我們來看下面一段程式碼:

    首先在類中宣告一個class類,和一個struct結構,如圖:

  並使用在程式入口呼叫它們,如圖

  

    現在我們來看一看,它們在記憶體當中是如何儲存的?

    從這張圖可以看出,class(類)例項化出來的物件,指向了記憶體堆中分配的空間

struct(結構)例項化出來的物件,是在記憶體棧中分配

   接下來,我們再來在上面的程式做如下修改:

   

   紅框,程式碼定義一個class例項化物件s2,然後把物件s1賦值給s2

    藍框,程式碼定義一個結構例項化物件r2,然後把物件r1賦值給r2

    那它們輸出的結果是多少呢?請選擇(   )

A、  s1的值為:12     s2的值為222
       r1的值為:16     r2的值為666

B、  s1的值為:12     s2的值為222
       r1的值為:666    r2的值為666

C、  s1的值為:222    s2的值為222
       r1的值為:16     r2的值為666

D、  s1的值為:222     s2的值為222
       r1的值為:666     r2的值為666

複製程式碼

正確答案是:C

為什麼會這樣呢?所以我們來看一看,多個值型別和引用型別在記憶體裡面是如何儲存的,如圖:

 從圖中,可以看出,兩個引用型別 s1,s2都指向了同一個拖管堆上的空間,

當某一個發生改變的時候,其於的會發生變化

而結構是值型別,雖然使用r2=r1,把r1物件賦值給r2,

     但是它會線上程棧中分配一個獨立的空間,

     當修改某一個物件的值的時候,

不會影響到另一個物件