值类型和引用类型

值类型和引用类型

一.使用和存储上的区别

变量类型的复习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//无符号整形
byte b=1;
ushort us=1;
uint ui=1;
ulong ul=1;
//有符号整形
sbyte sb=1;
short s=1;
int i=1;
long l=1;
//浮点数
float f=1f;
double d=1.1;
decimal de=1.1m;
//特殊类型
bool bo=true;
char c='A';
string str ="strs";
//复杂数据类型
enum 枚举
数组(一维,二维,交错)

我们可以把以上学过的变量类型分成值类型引用类型

引用类型:string,数组,类

值类型:其他,结构体

值类型和引用类型的区别

1.使用上的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int a=10;
int[] arr=new int[]{1,2,3,4};
int b=a;
//申明了一个b让其等于之前的a。
int[] arr2=arr;
//申明了一个arr2让其等于之前的arr。
Console.WriteLine("a={0},b={1},",a,b);
Console.WriteLine("arr[0]={0},arr2[0]={1},",arr[0],arr2[0]);
//输出结果,a=10,b=10。arr[0]=1,arr2[0]=1.
b=20;
arr2[0]=5;
//对数据进行修改
Console.WriteLine("a={0},b={1},",a,b);
Console.WriteLine("arr[0]={0},arr2[0]={1},",arr[0],arr2[0]);
//输出结果 a=10,b=20.arr[0]=5,arr2[0]=5.
//区别出来了。

由上述可见:值类型在相互赋值时,把内容拷贝给了对方,“它变我不变”。

而引用类型的相互赋值是让两者指向同一个位置,“它变我也变”。

2.为什么有以上区别?

值类型和引用类型存储的内存区域是不同的,存储方式是不同的,所以就造成了他们在使用上的区别。

值类型存储在栈空间 ——系统分配,自动回收,小而快。

引用类型存储在堆空间 ——需要手动申请和释放,大而慢。

(Ps:引用类型只是将引用类型的地址存放到栈里面,我们在调用时,会先调用引用类型的地址,用地址指向引用类型的值,引用类型的值放在堆空间中。)

下图为值类型赋值关系图

(b=a只是将a的值“拷贝”一份给b,a的值本身不影响。)

下图为引用类型赋值关系图

(我们arr2=arr是将arr的地址“拷贝”给arr2,使二者的地址相同,指向了堆中同一片区域,对arr2[0]的修改,其实是对堆内数据的修改,又因为arr和arr2地址相同,因此二者会进行同步的堆内数据修改。)

插入一种新的引用类型情况

1
2
3
arr2=new int[]{99,3,2,1} 
Console.WriteLine("arr[0]={0},arr2[0]={1},",arr[0],arr2[0]);
//在这种情况下,arr[0]=5,而arr2[0]=99;

这是为什么呢?

(由上图可知,如果arr2=new int[],相当于在堆空间中开辟了一片新的区域,arr2则存储了这一片新区域的新地址,因此,之后的修改自然和原来的arr没有关系了。

学了ref和out之后可以对这种情况进行解析了

二.特殊的引用类型string(!!!重要)

string的“它变我不变”

1
2
3
4
5
6
7
string str1="123";
string str2=str1;
str2="321";
//因为string是引用类型,按理说,应该是它变我也变。
Console.WriteLine(str1);
Console.WrtieLine(str2);
//最后却会输出123,321.变成它变我不变了。

为什么和普通的引用类型不一样???

string非常的特殊,它具备值类型的特征,它变我不变。

下图是string类型的存储过程。

(C#对string类型进行了特殊处理,str2重新赋值时,可以参考上面int数组的特殊情况(new情况),对str2的内容在堆空间重新分配了一片区域,自然的,受str2的地址也会发生新的变化了。)

Ps:string虽然方便,但是有一个小缺点,就是频繁的改变string,重新赋值时,会产生内存垃圾。(关于优化替代方案,我们会在面向对象之后进行讲解)


值类型和引用类型
https://gaster44.github.io/2023/11/21/值类型和引用类型/
作者
huangjinhong
发布于
2023年11月21日
许可协议