值类型和引用类型
值类型和引用类型
一.使用和存储上的区别
变量类型的复习
1 |
|
我们可以把以上学过的变量类型分成值类型和引用类型
引用类型:string,数组,类
值类型:其他,结构体
值类型和引用类型的区别
1.使用上的区别
1 |
|
由上述可见:值类型在相互赋值时,把内容拷贝给了对方,“它变我不变”。
而引用类型的相互赋值是让两者指向同一个位置,“它变我也变”。
2.为什么有以上区别?
值类型和引用类型存储的内存区域是不同的,存储方式是不同的,所以就造成了他们在使用上的区别。
值类型存储在栈空间 ——系统分配,自动回收,小而快。
引用类型存储在堆空间 ——需要手动申请和释放,大而慢。
(Ps:引用类型只是将引用类型的地址存放到栈里面,我们在调用时,会先调用引用类型的地址,用地址指向引用类型的值,引用类型的值放在堆空间中。)
下图为值类型赋值关系图
(b=a只是将a的值“拷贝”一份给b,a的值本身不影响。)
下图为引用类型赋值关系图
(我们arr2=arr是将arr的地址“拷贝”给arr2,使二者的地址相同,指向了堆中同一片区域,对arr2[0]的修改,其实是对堆内数据的修改,又因为arr和arr2地址相同,因此二者会进行同步的堆内数据修改。)
插入一种新的引用类型情况
1 |
|
这是为什么呢?
(由上图可知,如果arr2=new int[],相当于在堆空间中开辟了一片新的区域,arr2则存储了这一片新区域的新地址,因此,之后的修改自然和原来的arr没有关系了。
学了ref和out之后可以对这种情况进行解析了
二.特殊的引用类型string(!!!重要)
string的“它变我不变”
1 |
|
为什么和普通的引用类型不一样???
string非常的特殊,它具备值类型的特征,它变我不变。
下图是string类型的存储过程。
(C#对string类型进行了特殊处理,str2重新赋值时,可以参考上面int数组的特殊情况(new情况),对str2的内容在堆空间重新分配了一片区域,自然的,受str2的地址也会发生新的变化了。)
Ps:string虽然方便,但是有一个小缺点,就是频繁的改变string,重新赋值时,会产生内存垃圾。(关于优化替代方案,我们会在面向对象之后进行讲解)