您好,登錄后才能下訂單哦!
概說:
1.值類型變量中直接儲存變量的值,值類型的實例在內存中的儲存位置叫棧(stack)。性能很好,值類型只限于存在很小一塊的數據(所以的值類型必須小于16字節)
2.引用類型將其數據的地址保存在堆棧中,地址所指向的實際數據,保存在稱為堆(heap)的內存區域中。
對于堆和棧:
棧(操作系統):由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構中的棧
堆(操作系統): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似于鏈表。
堆(數據結構):堆可以被看成是一棵樹,如:堆排序
棧(數據結構):一種后進先出的的數據結構
下面是堆棧的分布:
棧:棧作為一種數據結構,是一種只能在一端進行插入和刪除操作的特殊線性表
堆棧可以從下面幾部分區別:
1.申請方式:
stack:
由系統自動分配。 例如,聲明在函數中一個局部變量 int b; 系統自動在棧中為b開辟空間
heap:
需要程序員自己申請,并指明大小,在c中malloc函數
2.申請效率的比較:
棧由系統自動分配,速度較快。但程序員是無法控制的。
堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便.
3.申請大小的限制:
棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩余空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
堆和棧的區別可以用如下的比喻來看出:
使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大
細說:
C#的值類型包括:結構體(數值類型,bool型,用戶定義的結構體),枚舉,可空類型。
C#的引用類型包括:數組,用戶定義的類、接口、委托,object,字符串。
數組的元素,不管是引用類型還是值類型,都存儲在托管堆上。
引用類型在棧中存儲一個引用,其實際的存儲位置位于托管堆。
值類型總是分配在它聲明的地方:作為字段時,跟隨其所屬的變量(實例)存儲;作為局部變量時,存儲在棧上。
值類型在內存管理方面具有更好的效率,并且不支持多態,適合用作存儲數據的載體;引用類型支持多態,適合用于定義應用程序的行為。
下面看一個例子:
using System; namespace TestValve { class MainClass { class Number1 //類類型屬于引用類型 { public int val; public Number1(int _val) {val=_val;} public override string ToString () { return val.ToString (); } } struct Number2 //結構類型屬于值類型 { public int val; public Number2(int _val) {val=_val;} public override string ToString () { return val.ToString (); } } public static void Main (string[] args) { Number1 n1 = new Number1 (0); //類類型的實例化 Number1 n2 = n1; n1.val += 1; n2.val += 2; Console.WriteLine ("n1={0},n2={1}",n1,n2); Number2 n3 = new Number2 (0); //結構類型的實例化 Number2 n4 = n3; n3.val += 1; n4.val += 2; Console.WriteLine ("n3={0},n4={1}", n3, n4); Console.ReadKey (); } } }
輸出結果:
“n3=1,n4=2”,因為結構式值類型,將一個值類型對象賦值給一個另一個變量將會創建兩個不同的實例對象,所以一個對象的改變不會影響到另一個對象,因為他們是兩個不同的對象,各有各的存儲位置。
“n1=3,n2=3”,因為類是引用類型,當修改一個引用類型變量的時候,你修改的是這個引用所指向的數據,所有指向同一個數據的引用,都會反應這樣的修改結果。引用類型的賦值其實是把地址賦給一個引用類型變量,這兩個變量都指向相同的地址單元,所有兩個引用類型之間會相互影響。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。