上一篇介紹了基礎資料型別 (Elementary Data Type),今天我們來介紹實值型別與參考型別!
一 什麼是實值型別與參考型別?
C#與大多數物件導向語言資料類型一樣,分為實值型別與參考型別兩種?如何區分這兩種類型?
根據類型結構圖我們得出:
1.實值型別包括 內建資料類型如(int double float) 使用者自訂實值型別(struct 結構體) 枚舉(emun)
2.參考型別包括 介面類型 類類型等等。
知道了那些類型屬於實值型別與那些類型屬於參考型別之後,我們來分析一下實值型別與參考型別的區別分別是什嗎?
首先繼續看圖:
根據我們可以看出,我們電腦記憶體可以分為堆(.NET中是託管堆)和棧兩個地區!理解了這個後我們來看實值型別和參考型別的區別:
1 實值型別:實值型別如 int double float 等這些基礎資料類型,實際的值都是分配在棧上!
2 參考型別: 參考型別如 object 等這些資料類型,實際的值都是分配在堆上,並且在棧上儲存一個堆上存放值的地址。
如 代碼:
1 //在棧上分配一個空間 存放10
2 int a = 10;
3
4 //在堆上分配一個空間存放變數a的值10,在棧上分配一個空間存放該值在堆中的地址
5 object o = a;
好的瞭解基本實值型別與參考型別的概念後我們來深入分析他們的本質。
二 實值型別與參考型別剖析
1 實值型別
實值型別是分配在棧中,根據棧的原理,實值型別一旦離開當前程式的範圍就會被立刻銷毀!那麼我定義兩個相同的實值型別會怎麼樣呢?看如下代碼:
static void main()
{
//此時在棧中分配一塊空間存放10
int a = 10;
//在棧中繼續分配一塊空間存放a的值 10
int b = a;
//修改b所存放的空間中的10為20
//此時不影響a 因為他們兩個各自有獨立的空間
b = 20;
//列印 a 和 b 的值
Console.WriteLine(" a = {0}",a.ToString());
Console.WriteLine(" b = {0}",b.ToString());
} //範圍結束 銷毀a 和 b 所分配的地址空間
運行結果:
2 參考型別
參考型別實際的值存放在堆中,在棧中分配堆中分配空間的地址。那麼當參考型別離開對象的範圍會發生什嗎?參考如下代碼:
1 class MyClass
2 {
3 public int a;
4 }
5
6 class Program
7 {
8 static void Main(string[] args)
9 {
10 //此時在堆中分配一個空間存放10,在棧中分配一個空間存放堆中10的空間地址
11 MyClass mc1 = new MyClass();
12 mc1.a = 10;
13
14 //此時在堆中又分配一個空間存放20,在棧中分配一個空間存放堆中20的空間地址
15 MyClass mc2 = new MyClass();
16 mc2.a = 20;
17
18 //此時將a中棧的地址賦值給b
19 //那麼此時 b 也指向 a在堆中分配的地址
20 //此時b原來指向的堆空間地址存放的20就被廢棄了
21 mc1 = mc2;
22
23 //修改該a 和 b 同時指向的堆空間的值為30
24 mc2.a = 30;
25
26 //列印結果
27 Console.WriteLine(" mc1.a = {0}", mc1.a);
28 Console.WriteLine(" mc2.a = {0}", mc2.a);
29
30 }
31 }
運行結果如下:
好的今天就介紹到這裡,下一篇將介紹裝箱與拆箱。