值型別與引用型別的區別

chinaherolts2008發表於2020-12-13

一、概念講解:
1、值型別:

包括:sbyte、short、int、long、float、double、decimal(以上值型別有符號)

byte、ushort、uint、ulong(以上值型別無符號)

bool、char

2、引用型別:

包括:物件型別、動態型別、字串型別

二、具體區別:
1、值型別:

byte b1 = 1;
byte b2 = b1;
Console.WriteLine("{0},{1}。", b1, b2);
b2 = 2;
Console.WriteLine("{0},{1}。", b1, b2);
Console.ReadKey();

解釋:

在這裡插入圖片描述

byte b1 = 1;宣告b1時,在棧內開闢一個記憶體空間儲存b1的值1。

byte b2 = b1;宣告b2時,在棧內開闢一個記憶體空間儲存b1賦給b2的值1。

Console.WriteLine("{0},{1}。", b1, b2);輸出結果為1,1。

b2 = 2;將b2在棧中儲存的值1改為2。

Console.WriteLine("{0},{1}。", b1, b2);輸出結果為1,2。

2、引用型別:

string[] str1 = new string[] { "a", "b", "c" };
string[] str2 = str1;
for (int i = 0; i < str1.Length; i++)
{
    Console.Write(str1[i] + " ");
}
Console.WriteLine();
for (int i = 0; i < str2.Length; i++)
{
    Console.Write(str2[i] + " ");
}
Console.WriteLine();
str2[2] = "d";
for (int i = 0; i < str1.Length; i++)
{
    Console.Write(str1[i] + " ");
}
Console.WriteLine();
for (int i = 0; i < str2.Length; i++)
{
    Console.Write(str2[i] + " ");
}
Console.ReadKey();

解釋:

在這裡插入圖片描述

string[] str1 = new string[] { “a”, “b”, “c” };宣告str1時,首先在堆中開闢一個記憶體空間儲存str1的值(假設:0a001),然後在棧中開闢一個記憶體空間儲存0a001地址

string[] str2 = str1;宣告str2時,在棧中開闢一個記憶體空間儲存str1賦給str2的地址

for (int i = 0; i < str1.Length; i++)

{

  Console.Write(str1[i] + " ");

}

Console.WriteLine();

for (int i = 0; i < str2.Length; i++)

{

  Console.Write(str2[i] + " ");

}

Console.WriteLine();

輸出結果為:

a b c

a b c

str2[2] = “d”;修改值是修改0a001的值

for (int i = 0; i < str1.Length; i++)

{

  Console.Write(str1[i] + " ");

}

Console.WriteLine();

for (int i = 0; i < str2.Length; i++)

{

  Console.Write(str2[i] + " ");

}

輸出結果為:

a b d

a b d

3、string型別:(特殊)


string str1 = "abc";
string str2 = str1;
Console.WriteLine("{0},{1}。", str1, str2);
str2 = "abd";
Console.WriteLine("{0},{1}。", str1, str2);
Console.ReadKey();

解釋:

在這裡插入圖片描述

string str1 = “abc”;宣告str1時,首先在堆中開闢一個記憶體空間儲存str1的值(假設:0a001),然後在棧中開闢一個記憶體空間儲存0a001地址

string str2 = str1;宣告str2時,首先在堆中開闢一個記憶體空間儲存str1賦給str2的值(假設:0a002),然後在棧中開闢一個記憶體空間儲存0a002的地址

Console.WriteLine("{0},{1}。", str1, str2);輸出結果為:
abc
abc

str2 = “abd”;修改str2時,在堆中開闢一個記憶體空間儲存修改後的值(假設:0a003),然後在棧中修改str2地址為0a003地址

Console.WriteLine("{0},{1}。", str1, str2);輸出結果為:
abc
abd

堆中記憶體空間0a002將被垃圾回收利用。

以上是我對值型別與引用型別的理解,希望可以給需要的朋友帶來幫助。

給自己留了後路相當於是勸自己不要全力以赴。

相關文章