参考了帖子:C#的两种类据类型:值类型和引用类型_牛奶咖啡13的博客-CSDN博客
今天因为对值类型和引用类型的不清晰导致赋值过程出错,特此记录一下。
核心(我的理解):值类型直接存储其值,而引用类型存储它在堆上的地址,根据堆上的地址读出其值
具体上代码:
class SomeClass //引用类型
{
public int val;
}
struct SomeStruct //值类型
{
public int val;
}
static void Main(string[] args)
{
SomeClass[] sc = new SomeClass[10];
SomeClass sc1 = new SomeClass(); //引用类型在栈上存储的是堆上分配的临时内存的地址
SomeStruct[] ss = new SomeStruct[10];
SomeStruct ss1 ; //值类型在栈上存储的是实际的数值
int j = 0;
for(int i = 0; i<10; i++)
{
sc1.val = i;
ss1.val = i;
ss[j] = ss1;
sc[j] = sc1; //赋值过程赋值的是地址
j++;
}
Console.WriteLine("以下是引用类型的赋值:");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(sc[i].val);
}
Console.WriteLine("以下是值类型的赋值:");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(ss[i].val);
}
j = 0;
//想要引用类型达到和值类型一样的复制效果,需要将要每次赋值的引用类型申明一个临时地址,也就是此地址可变
for (int i = 0; i < 10; i++)
{
SomeClass st1 = new SomeClass(); //每次进入循环后他的地址都会改变
st1.val = i;
sc[j] = st1; //赋值过程赋值的是地址
j++;
}
Console.WriteLine("以下是引用类型修改后的赋值:");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(sc[i].val);
}
}
结果如下图:
注意区分以下两种写法:
第一种:代码如下,过程图类似下图(图中地址不代表任何实际意义,只是作为示意)
SomeClass[] sc = new SomeClass[10];
SomeClass sc1 = new SomeClass(); //引用类型在栈上存储的是堆上分配的临时内存的地址
int j = 0;
for(int i = 0; i<10; i++)
{
sc1.val = i;
sc[j] = sc1; //赋值过程赋值的是地址
j++;
}
第一种:代码如下,过程图类似下图(图中地址不代表任何实际意义,只是作为示意)
SomeClass[] sc = new SomeClass[10];
int j = 0;
for(int i = 0; i<10; i++)
{
SomeClass sc1 = new SomeClass(); //引用类型在栈上存储的是堆上分配的临时内存的地址
sc1.val = i;
sc[j] = sc1; //赋值过程赋值的是地址
j++;
}