值类型和引用类型由来及详解(C++/C#混讲)

作者在初学值类型、引用类型时就一头雾水,相信大部分人也是一样的,现在回过头来总结一下。

 

说起值类型、引用类型这件事呀,那就得从头说起...

 

  数据都是存放在内存中的,这一点毋庸置疑。

  首先,我们可以将程序运行时存于内存中的数据简单分为两类。

  第一类是数据结构简单、单一,并且数据量不大的对象。对于此类数据,我们希望其读写速度能够尽量快,并且也希望在程序不需要用到这些数据时能够自动删除并释放所占的内存空间

  第二类是数据结构复杂、数据量较大,并且通常需要在各函数体之间传递的对象。对于此类数据,我们希望有一块内存能够长久的存放该类数据,同时也希望实现在不同函数体之间,能快速的访问相同对象(数据)

 

于是乎,聪明的程序员们发明了两个东西。

 

  一个名为栈内存,其特点是空间小、读写速度快、数据先进后出,后进先出(读写速度快是因为,代码每进入到一个函数体中,就会提前为该函数体申请一块栈内存空间,用于存放函数体中变量的数据,在退出函数时自动释放申请的栈内存);

  另一个名为堆内存,其特点是空间大、读写速度较慢、存入的数据在没有手动删除之前将始终保留至整个程序生命周期结束(读写速度慢是因为,所有程序都共享除栈内存外剩下的堆内存,而对于堆内存中空间的申请则需要由操作系统在各程序之间统一协调、调度、发放,所以显得慢)

 

下面,我们来用刚刚发明的栈内存、堆内存来推演一下。  

 

  我们举个最简单的例子,Function1()中函数Function2()的调用。程序先进入外层函数Function1(),随着外层函数体代码的执行,接而又进入内层函数Function2()中,随着Function2()代码执行完毕,则退出Function2()回到Function1()函数体中,再等至Function1()中代码执行完毕就退出Function1()。我们可以发现,先进入的Function1()其实是最后退出的,而最后进入的Function2()又是先退出的

  我们知道程序的运行其实就可以简单的认为是在不同函数体内' 穿梭 ',而这个' 穿梭 '的的方式其实便是:先进后出、后进先出。大家可以惊讶的发现,这貌似就是栈的特性!!!

  此番不谋而合后,大佬们从此就定下了,将上述说明的第一类数据定义为' 值类型 '数据。' 值类型 '数据在函数体中被创建时便将其数据本身存放在函数体申请的栈内存中。

 

  然后,我们来把第二类数据套入到' 堆内存 '这个模型中。

  对于第二类数据结构复杂且很有可能需要在各函数之间频繁传递且访问的数据,存于一个对程序而言空间大、可永久存储、可随时申请、随时释放的地方是最合适不过了,而这个地方便是之前发明的堆内存。

  于是大佬们又定义了一个称为' 引用类型 '的东西,今后便把' 引用类型 '数据存于堆内存中。程序通过地址访问该数据,而这个地址其实就是引用类型变量本身(引用变量本身作为地址,其实是存放于函数体申请的栈内存中的,原因显而易见,函数体内变量的生命周期随着函数体的生命周期走)这样定义后,在不同函数之间引用类型数据就通过地址的传递实现在不同函数中访问同一个对象

   

总结: 

  在C#中值类型有:整型:Int; 长整型:long; 浮点型:float; 字符型:char; 布尔型:bool 枚举:enum 结构:struct,余下皆是引用类型。

  而在C++中却没有明确的值类型和引用类型的概念,因为C++中默认都是' 值类型 ',而所谓的' 引用类型 '其实是通过new的方式在堆上申请空间并返回存储对象地址而实现的(例如 int* a = new int(5),这时‘ 5 ’这个数据便存放在堆中,而a则成为访问‘ 5 ’数据的一个地址,也就光荣成为了引用类型变量)。

  C#中的' ref ',' out '关键字并不是能够将值类型转化成引用类型,因为用了ref的值类型数据依旧存于栈内存中。只不过ref的功能同C++中的指针一样,它将值类型数据的指针传入方法体,使得方法体内外访问的都是同一个对象。

  对于栈内存中的数据,程序员们并不需要管理其生命周期;而对于堆空间中的数据,则需要手动释放,对于C#而言,有CLR的垃圾回收机制帮忙自动回收后续没有再使用的堆内存中的数据;而对于C++而言则需要通过delete实现释放。

 

最后讲个笑话

  最开始学C++时,同时遇到int* a和int *a,对于一个空格的差异,在严谨的编程世界,我本能的认为这俩是有本质区别的,直到我把整本书都翻遍,都没见到解释二者区别的描述...这个疑惑一直藏在心中好久,直到某一次在CSDN上看到解释...这俩压根就没区别!!!!

 

参考:

https://blog.csdn.net/weixin_53472920/article/details/119744114?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0-119744114-blog-109323575.pc_relevant_aa&spm=1001.2101.3001.4242.1&utm_relevant_index=3

https://blog.csdn.net/ananlele_/article/details/109025276

posted @ 2022-12-22 11:23  ShawBlack  阅读(307)  评论(0编辑  收藏  举报