標籤:style blog http color io ar 資料 sp div
記得大三上學期上C#課程的時候,老師第一堂課就重點給我們講了一下C#中的資料類型。我們都知道,C#是一門強型別的進階程式設計語言,瞭解它的資料類型是非常有必要的。老師當時給我們列舉了很多資料類型,然後問我們哪些是實值型別,那些是參考型別。說實話,當時對於這個問題還真是回答不上來,或許可以說是自己沒有多少底氣回答。雖然大一學C++的時候接觸過實值型別和參考型別,但是因為沒有深究,或者根本沒有真正瞭解他們的區別,以至於在自己寫代碼時無形當中用到了卻還是不瞭解它們之間的具體區別。
現在大四了,也到了快緊張面試的時候,自己也會去找一些關於.net方面的面試題看。通過一些途徑瞭解到,有很多企業在面試時把基礎放在重要的位置,像今天所說的實值型別和參考型別的問題在ASPNet等Web方向的面試中就可能經常出現,所以我覺得很有必要好好弄清以下這兩個概念以及它們之間的區別。
以前,在我印象中,可能就是把實值型別理解為我們常用的那些基礎資料型別 (Elementary Data Type)(整形、浮點型、字元型、字串、結構體等等),把參考型別理解為類、指標等,其實這樣的理解是不全面的甚至可以說是錯誤的。那麼究竟什麼是實值型別,什麼又是參考型別呢?
整體來說,C#的實值型別有:
整型:int;長整型:long;浮點型:float;字元型:char;布爾型:bool;枚舉:enum;結構體:struct
C#的參考型別有:
類:class;介面:interface;數組:int[],string[];委託;裝箱實值型別
為了方便大家記憶和理解,我從網上找來一張圖展示實值型別和參考型別,清晰易懂
我們可以看到,C#中的實值型別包括7種資料類型,這裡要特別注意,並不是所有的基礎資料型別 (Elementary Data Type)都是實值型別,像string就是參考型別,我們可以把它看成一個類。還有一點,結構體雖然與類有點相似,但它是實值型別,類是參考型別,這是他們主要的區別之一。然後參考型別中類和介面大家都能接受,但是不能忘了數組也是參考型別,委託和裝箱實值型別因為目前我還不是很瞭解,所以只能強記了。但是說到委託,那必須值得一提,這是C#中一個非常重要的知識點,函數名作為參數傳遞調用是多麼的神奇,想想就有點小激動。但現在寫代碼我幾乎沒怎麼用委託,由此看來我必須要好好瞭解一下委託,找機會針對委託寫一片關於“探索C#中的委託”的部落格。
瞭解了實值型別和參考型別之後,那它們的區別是什麼呢?
從概念上看,實值型別的變數直接存放實際的資料,而參考型別的變數存放的則是資料的地址,即對象的引用。
從記憶體空間上看,實值型別的資料存放區在記憶體的棧中,範圍結束時,所佔空間自行釋放,效率高,無需進行地址轉換;而參考型別的資料存放區在記憶體的託管堆中,記憶體單元中只存放堆中對象的地址,由GC來控制其回收,需要進行地址轉換,效率降低,這也正是C#需要定義兩種資料類型的原因之一。
實值型別和參考型別在函數參數傳值時是有區別的,首先來看一段經過自己運行並成功的代碼:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace ConsoleApplication1{ class Person { public int Blood = 10; } class Program { public static void Add(int x) { x += 10; Console.WriteLine("實值型別當參數被傳遞並修改之後:" + x); } public static void Add(Person person) { person.Blood += 10; Console.WriteLine("參考型別當參數被傳遞並修改之後:" + person.Blood); } static void Main(string[] args) { //實值型別變數 int i = 10; Console.WriteLine("i的原值:" + i); Add(i); Console.WriteLine("但是i的值並沒有因為函數的修改而修改:" + i + ‘\n‘); //參考型別變數 Person person = new Person(); Console.WriteLine("Blood的原值:" + person.Blood); Add(person); Console.WriteLine("但是Blood的值因為函數的修改而修改:" + person.Blood); //實值型別和參考型別的區別,就在於當函數參數傳遞的時候. //實值型別是把自己的值複製一份傳遞給別的函數操作.無論複製的值怎麼被改變.其自身的值是不會改變的 //而參考型別是把自己的記憶體位址傳遞給別的函數操作.操作的就是參考型別值的本身.所以值被函數改變了. //這就是傳值和傳址的區別 Console.ReadLine(); } }}
從以下結果可以看到兩種類型函數傳參時的區別:(以上代碼中的注釋解釋了原因)
那麼文章就先寫到這裡了,初次寫部落格,或許存在很多問題,如有問題歡迎大家指出,我將認真改正。寫這篇部落格是為了讓自己在寫的過程中理解一些知識及備忘,研究的並不是那麼深入,或許不夠完善,還望大家見諒。
探索C#中的實值型別和參考型別