1、在講堆和棧之前,我們先看看值類型和引用類型:
(1)值類型
A:基本數據類型
a:int:整型
b:long:長整型
c:float:浮點型
d:char:字符型
e:bool:布爾型
B:枚舉類型
枚舉:enum
C:結構類型
結構:struct
(2)引用類型
A:類
a:基類:System.Object
b:字符串:string
c:自定義類:class
B:接口
接口:interface
C:數組
數組:int[],string[]
2、值類型和引用類型的存儲方式
值類型:值類型總是分配在它聲明的地方,作爲局部變量時,存儲在棧上;類對象的字段時,則跟隨這個類存儲在堆中。
引用類型:引用類型存儲在堆中。類型實例化的時候,會在堆中開闢一部分空間存儲類的實例。類對象的引用還是存儲在棧中。
Class Program
{
static void Main(string[] args)
{
//s:對象的引用【存儲在棧中】
//new Student()【對象存儲在堆中】
Student s=new Student();//引用類型
//局部變量【存儲在棧中】
int a =1;//值類型
}
}
class Student
{
//類的字段【跟隨這個類存儲在堆中】
public int Age=1;//值類型
}
3、引用類型和值類型的不同
(1)引用類型和值類型都繼承自System.Object類。不同之處,幾乎所有的引用類型都是直接從System.Object繼承,而值類型則是繼承System.Object的子類System.ValueType類。
(2)我們在給引用類型的變量賦值的時候,其實只是賦值了對象的引用;而給值類型變量賦值的時候是創建了一個副本(即克隆了一個變量)。
Class Program
{
static void Main(string[] args)
{
//引用類型賦值
Student s=new Student();
s.Age=10;
Student s2=s;//給引用類型的變量賦值的時候,其實只是賦值了對象的引用
s2.Age=20;
Console.RriteLine(s.Age);//20
//值類型賦值
int a =0;
int a2=a;//給值類型變量賦值的時候是創建了一個副本
a2=10;
Console.WriteLine(a);//0
}
}
class Program
{
public int Age=0;
}
4、引用類型和值類型的內存分配情況
class Program
{
static void Main(string[] args)
{
int i=10;//int類型在棧中佔了4個字節
Student s=new Student();//一個對象的引用在棧中佔了4個字節
long j=10;//long類型在棧中佔了8個字節
}
}
class Student
{
public int Age1=10;
public int Age2=20;
}
總結:棧的結構是先進後出;棧地址從高往低分配;類型的引用也存儲在棧中