由堆棧所能想到的??
提到堆棧區別,大部分首先想到的是,“值類型存儲在棧中,引用類型存儲在堆中,引用類型在棧上存儲指向堆的地址”這句話。說這個我先想說一下值類型和引用類型,以及值傳遞和引用傳遞,關於值類型有哪些,以及引用類型有哪些,這些可以自己去了解。
將一個值類型賦值給另一個值類型,是將值得本身全部賦值過去,簡言之,就是值類型的值傳遞傳遞的是值得本身,如下
class Program
{
//值傳遞&引用傳遞
static void Main(string[] args)
{
//值類型:int double char bool enum... 存儲值的
//引用類型:string 數組 自定義類,集合 object.. 存儲對值的引用的(可以理解爲存儲值在堆中的數據地址)
//這裏有篇博客說的很好:http://www.cnblogs.com/jiajiayuan/archive/2011/09/23/2185966.html
unsafe
{
//值傳遞
int n1 = 10;//地址:0x058***98
int n2 = 20;//地址:0x058***94
n1 = n2;
int* adress_n1 = &n1;//使用C#指針需要將語句塊標記爲unsafe表示不安全上下文
int* adress_n2 = &n2;
Console.WriteLine(n1);
Console.WriteLine(n2);
Console.WriteLine((int)adress_n1);//輸出n1在棧上的地址
Console.WriteLine((int)adress_n2);//輸出n2在堆棧上面的地址
Console.ReadKey();
}
}
}
值傳遞編輯圖示
flag:這裏待會將會和ref關鍵字有聯繫。
下面可以看看引用類型的引用傳遞又是怎麼一回事。
//引用傳遞
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "pc";
Person p2 = new Person();
p2.Name = "ppcc";
p2 = p1;
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);
Console.ReadLine();
}
}
public class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
引用傳遞編輯圖示
我們知道字符串也是引用類型,但是對於字符串由於字符串擁有不可變性,所以很特殊。
static void Main(string[] args)
{
string s1 = "pc";//字符串引用類型,但是字符串擁有不可變性
string s2 = s1;
s2 = "ppcc";
Console.WriteLine(s1);
Console.WriteLine(s2);
Console.ReadLine();
//輸出結果
//pc
//ppcc
}
ref參數
static void Main(string[] args)
{
int a = 20;
Test1(a);
Console.WriteLine(a);//輸出是多少?是20
Console.ReadLine();
}
public static void Test1(int a1)
{
a1 += 1;
}
在Test1裏面a的值是21,但是這個方法由於沒有返回值,所以,最後輸出結果還是原值。那這個例子和ref參數就有關了,有資料說,ref參數可以將值類型的傳遞改成傳遞地址,通過對地址的操作改變值類型本身。
static void Main(string[] args)
{
int a = 20;
Test1(ref a);
Console.WriteLine(a);//輸出是多少?是21
Console.ReadLine();
}
public static void Test1(ref int a1)
{
a1 += 1;
}
關於它和out參數的區別,記住一句話,因爲ref參數是從外部傳遞到函數裏面的,所以要求必須在函數外部進行賦值,而out參數因爲是從方法內部傳遞出去的,所以要求在方法內部必須對其進行有值操作。
out參數
static void Main(string[] args)
{
int a = 20;
int b;//使用out參數的時候 這裏不用賦值,因爲值是從一個函數裏面傳遞出來的
//Test1(ref a);
Test2(out b);
Console.WriteLine(b);//輸出是多少?是-1
Console.ReadLine();
}
//public static void Test1(ref int a1)
//{
// a1 += 1;
//}
public static void Test2(out int b)
{
b = 3;//在函數內部必須賦值
b -= 1;
}
留下的思考就是,out參數是否也是通過改變參數的傳遞方式?鏈接一個爲什麼C#中屬性不可以使用ref,out參數
http://book.51cto.com/art/200910/158498.htm