首页 技术 正文
技术 2022年11月19日
0 收藏 945 点赞 3,130 浏览 1636 个字

前言

这几天一直在思考这章讨论什么, 在上一章讨论string的时候牵涉到引用类型,那么我们这一章讨论讨论一下,值类型和引用类型。

值类型和引用类型,它们的区别来源于传值方式。有人会认为值类型就存在栈上这是不一定的。详细看下文。

有些人会说啊。。有垃圾回收机制进行清理内存。。不需要去折腾那么多吧 – -!。。。。。为了写好代码,避免面试问到。。还是勉为其难的讨论讨论吧。。。。。

值类型和栈

栈,存储不是对象成员的值数据类型,还存放着局部变量,参数。

那么他的工作原理是怎样的呢?首先要知道,数据在栈上,是从高内存位置往低内存位置填充的,变量地址不会重复的。

C#系列之值类型和引用类型

假如有下面一段代码:

  C#系列之值类型和引用类型

从上面可以看见,b代码块是嵌套a代码块里。由于代码从上到下的执行顺序,那么变量a会比变量b先入栈;可是b代码块会比a代码早结束,超出作用域之后,变量就会释放,因此,变量b会比变量a先释放。

C#系列之值类型和引用类型C#系列之值类型和引用类型

由此可见,灵活性并不高,如果希望生命活得长久点?这个时候,堆的作用就体现出来。

 

引用类型和堆

堆,它的特性和栈有点相反,存储的是对象成员类型,是从低内存位置往高内存位置填充的。当值类型的变量为类型成员的时候,是与对象存放在堆里。

先说下工作原理,有这样一段代码。

class Program
{
static void Main(string[] args)
{
Human h;
h = new Human();
}
}

首先,会在栈上分配一个空间,存放引用h,它仅仅是一个引用,不是对象。到第二句进行实例化对象,new 运算符是用来请求分配储存空间的,CLR会搜索堆上足够的位置,分配给对象,然后new会返回它所在堆上的地址给引用。因此在栈上存放着该引用指向堆上的对象的地址。

综上所述:

值类型的使用减少了堆的压力,同时减少垃圾回收的次数。引用类型却弥补了生命周期的不足,增加了灵活性。

值类型创建变量时是赋予默认值的,例如int默认值是0。而引用类型创建变量,默认是null。那么,没有对象的引用类型的变量使用时会报异常NullReferenceException。

值类型的变量是以复制的方式赋值,执行一次逐字段的复制,而引用类型将对象在堆上的地址赋于新变量进行引用。

下面有段代码充分说明了引用类型和值类型的区别 :(借用Clr C#的例子)

struct Struct//值类型
{
public int x;
}class Class //引用类型
{
public int x;
}class Program
{
static void Main(string[] args)
{
//代码A
Struct s1 = new Struct(); //分配在栈上
Class c1 = new Class(); //分配在堆上
s1.x = ;
c1.x = ; Console.WriteLine(s1.x); //输出1
Console.WriteLine(c1.x); //输出1 //代码B
Struct s2 = s1; //复制栈上成员给s2
Class c2 = c1; //复制引用给c2
s2.x = ; //值类型,s1.x不变,s2.x 变更
c2.x = ; //引用类型,c1.x和c2.x 同时改变 Console.WriteLine(s1.x); //1 值类型
Console.WriteLine(s2.x); //2 值类型 Console.WriteLine(c1.x); //2 引用类型
Console.WriteLine(c2.x); //2 引用类型
}
}

  c1将地址复制给c2,也就是说c1和c2指向的是同一个对象,因此c1和c2其中一个修改了,另外的也会受影响。

  s1将成员复制给s2,虽然s1和s2存储了相同的值,但是他们内存地址都不相同,存的是属于自己的值,因此s1和s2其实一个修改了,也不会影响另外一个。

结尾

    写到这里也差不多了。其实说到引用类型和值类型,还说牵涉到装箱和拆箱的,小弟对那块还没多深的了解,等以后再和大家探讨。  感冒了。。休息去。。。一个多星期还没好,今天貌似又严重了。。公司的流感太厉害了。。希望各位注意身体。。=。=。。。。。

下一篇: Web classPath
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,105
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,582
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,429
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,836
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,919