《程序是怎样跑起来的》第四章——熟练使用有棱有角的内存

关于这一章,是目前让我最感兴趣的一章,因为说到了内存,在编程过程中我经常遇到内存这类的问题,如堆、栈溢出,如何更好的使用内存,所以对内存格外想要了解。

内存是一种名为内存IC的电子元件,有多种类型如:

主存储器(Main Memory):也称为内部存储器或随机存取存储器(RAM),用于临时存储程序和数据,是计算机 CPU 直接访问的内存。主存储器包括静态RAM(SRAM)和动态RAM(DRAM)等形式。

  • 缓存存储器(Cache Memory):位于主存储器和 CPU 之间,用于加快对常用数据和指令的访问速度。主要包括一级缓存(L1 Cache)、二级缓存(L2 Cache)和三级缓存(L3 Cache)等。

  • 虚拟内存(Virtual Memory):通过在硬盘上模拟内存空间,扩展物理内存的容量,提高系统的稳定性和多任务处理能力。

  • 只读存储器(Read-Only Memory,ROM):包括一次性可编程存储器(OTPROM)、闪存存储器等,用于存储固定的程序和数据,通常不可被修改。

  • 闪存存储器(Flash Memory):用于长期存储数据,如固态硬盘(SSD)、USB 闪存驱动器等,具有电擦除和可编程特性。

  • 缓冲存储器(Buffer Memory):用于暂时存储数据,平衡数据传输速度不匹配的设备之间的数据传输。

  • 寄存器(Register):位于 CPU 内部的最快速、最小容量的存储器,用于存储指令和数据,CPU 直接访问。

内存IC中有电源、控制信号、地址信号、数据信号。通过地址来进行读写。对于我们来说,内存的实体不用过多了解,在程序员的眼中内存可以假想为楼房,每一层中的人就是数据。而在程序中每一层的数据中还引入了数据类型的使用,来控制“人的大小”就是占用内存的大小。

现在来了解一下指针,指针是学习C语言绕不过去了一题。而指针其实也是变量。表示的不是数据的值,而是存储数据的地址。通过指针来对指定地址的数据进行读写操作。

了解了基础知识,那么如何熟练使用有棱有角的内存呢?就是使用数组。数组是只多个数据类型相同的数据连续在内存中排列的一种形式。各个元素通过各自的编号来区分。这个编号就是索引。通过对数组的使用能让我们的代码变得更加的高效和简洁。数组使我们学习中重要的一部分,需要熟练掌握数组和数值的各种变形,栈,队列和各种容器等等。

栈和队列的区别在于数据出入的顺序是不同的,栈使用的是后入先出的方式(LIFO),而队列使用的是先入先出的方式(FIIFO)。如果要在程序中实现栈和队列,需要适当的元素数来定义存储数据的数组,和对数组进行读写的函数,将数据写入栈的函数名为Push,读出的函数名为Pop,往队列中写入数据的函数名为Enqueue,读出的函数为Dequeue。他们分别组成一队函数,通过对它们的使用来操作栈和队列。

例:

运行:

 栈(后入先出):

 队列(先入先出):

 如图队列的读写机制如同排队一样,而队列的实现一般是使用环状缓冲区(ring buffer),如图,读写也就循环起来了:

栈和队列都是不用考虑索引的顺序来进行读写的方式,接下来的链表和二叉查找树,链表可以更高效的对数组(元素)进行追加和删除的操作。二叉查找树可以对数组进行更高效的检索。

链表:在数组的各个元素上为其附带上 上下的元素的索引就可实现链表。数据的值和先一个元素的索引就构成了数组的一个元素。

在链表中删除一个中间元素,无需将下边各各元素向前移动,链表对自动补位,就省去了移动大量元素的操作。

二叉查找树:指在链表的基础上往数组中追加元素时考虑数据的大小关系,将其分为左右两个方向存储的表现形式。

 二叉查找树的便利之处在于,对数据的搜索能力更有效率,二叉查找树是由链表构造发展的表现形式,因此在数据的追加好删除也同样有效。

 

 

 

posted @   琦q  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示