【C#】—值类型与引用类型

前言

C#的类型系统可分为两种类型,一是值类型,一是引用类型。在C#中每种类型的存储方式又分为两种,一是分配在托管栈中(简称栈),一是分配在托管堆中(简称堆)。内存的分配有CLR管理,即CLR(公共语言运行库,Common Language Runtime)和Java虚拟机一样也是一个运行时环境,是一个可由多种编程语言使用的运行环境。


数据类型

1、概念

值类型:数据存储在内存的堆栈中,从堆栈中可以快速的访问这些数据,因此,值类型表示实际的数据。

引用类型:表示指向存储在内存堆中的数据的指针或引用


栈:栈是编译期间就分配好的内存空间,因此代码中必须就栈的大小有明确的定义。分配在托管栈中的变量会在创建它们的方法返回时自动释放。

:堆是程序运行期间动态分配的内存空间,可以根据程序的运行情况确定要分配的对内存的大小。分配在托管堆中的变量并不会在创建它们的方法结束时释放内存,它们所占用的内存会被CLR中的垃圾回收机制释放。



2、区别

基本区别在于它们的存储方式,值类型只将值存放在内存中,这些值类型都存储在堆栈中。而引用类型的内存单元只存放内存堆中对象的地址,而对象本身放在内存堆中。

值类型直接从堆栈中里面取值,而引用类型必须要先从堆栈里面取出它的地址,再根据这个地址在堆里找到对应的值。


3、分类



4、举例

举例对象为结构和类,结构属于值类型,类属于引用类型。

第一步:创建p1和p2,给p1赋值,然后让p2=p1,代码如下:


对于上述代码,放在结构和类中,运行结果是一样的,结果如下:


解释:

结果一样,但是理念不一样。在结构中,栈中存放的就是值,p1和p2在栈中都有各自的内存空间,p2=p1,是将p1的值赋值给p2。在类中,p1和p2在栈中存放的各自的地址,在堆中存放的是值,p2=p1,不是将p1的值赋给p2,而是表示p2和p1一样,将指针指向堆中的值。


第二步:在给p2赋新值,同样的代码放在结构和类中,结果是不一样的:


(1)如果代码是放在结构中,结果如下:


解释:


在结构中,即对于值类型,在变量p1、p2创建时已分配好了内存空间,所以在给p2赋新值前,p1和p2各自空间中的值是相同,当给p2赋新值后,p1空间的值不会改变,只是把p2原先的值给替换了,所以,结果是


(2)如果代码是放在类中,结果如下:


解释:


在类中,即对于引用类型,栈中存放的地址,p1和p2有不同的地址,值存放在堆中(为引用类型对象赋值时,似乎是引用类型必须要先从堆栈里面取出它的地址,再根据这个地址在堆里找到对应的值。)。p1=p2,代表他俩的地址会指向相同的值,当给p2赋新值后,p2会指向新值,因为p1和p2的地址相同,所以p1也会指向新值。所以结果相同。


小结

最经典的总结就是:值类型栈和堆中存放的值,引用类型,栈中存放的是地址,堆中存放的值。以上的内容有一些个人的理解,若有不正确的地方,望各位大侠指出微笑


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 36
    评论
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子松的猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值