堆疊(Stack)和堆積(Heap) 還有Boxing與Unboxing觀念釐清
大家應該都知道數值型別跟參考型別的差異,不過上次保哥問了我知不知道Stack是什
麼,我還真是一點印象都沒有。
最近翻了循序漸進學 Visual C# 2008 官方版教材 這本書,雖然內容都是基本語法,
但是很多觀念都解釋的滿清楚的。看了之後覺得以前懵懵懂懂的語法,都清楚了不少。
堆疊(Stack)和堆積(Heap) 是存放資料的記憶體分成兩種不同的管理機制。
堆疊可以想像成一個一個疊起來的盒子,數值型別的變數就一個一個放在盒子內。當變
數生命周期結束時,盒子就會被移走。
堆積就像一個空地內亂七八糟的擺了一堆盒子,然後盒子上有標明這個盒子目前是屬於
誰在使用的(可以很多人使用同一個盒子)。每當new 出一個物件,例如:
Customer c = new Customer();
物件參照 c 就擺放在堆疊中的盒子裡,而new出來的物件Customer()就在堆積中找一個沒
人用的空盒子來擺。當c的生命周期結束,也就是Customer()沒人使用時,堆積中的盒子
就會被註明為沒人使用,系統會不定時的把沒人使用的盒子清空。
差不多就是這樣。不過,這個東西跟學C#有什麼關係?
有時候不懂數值型別跟參考型別的差異,寫程式會發生想不通的錯誤。
例如我明明只改了這個數的值,為什麼另外一個數的值也會跟著變之類的問題。
但是最主要的還是為了講Boxing(裝箱)跟Unboxing(拆箱)的關係
在講之前還要再提一個萬物之母的類別 "Object"
Object是一種參考型別,也是所以類別的源頭。因此Object可以指向任何的參考型別。
但是當Object指向數值型別時,那會怎麼樣?
int 數值 = 100 ;
object o = 數值 ;
參考型別是擺在堆積裡,數值型別是擺在堆疊裡。那...Object指向數值型別到底該擺哪?
這個時候,就會將100從堆疊中複製一份到堆積中的盒子裡,然後o這個物件參考指向這
個盒子。這種將堆疊中的值複製到堆積中的行為,就叫Boxing(裝箱)。
反過來說,將堆積中的值,複製到堆疊中的行為,就叫Unboxing(拆箱)。
int 值 = (int) o ; // 將o拆箱
那,講了這麼多,這跟寫程式有什麼關係?
因為裝箱跟拆箱的過程,會消耗不少程式效能。所以才會為什麼有了集合,還要有泛型
只是這種效能差異,如果程式不夠大,也感覺不出來。
但是學習儘量秉持的知其然,還要知其所以然。
了解一些背後的原理,才能更正確的選擇所寫的語法。