必备常识之内存

什么是内存
内存(Memory) 是计算机中最重要的部件之一,它是程序与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存对计算机的影响非常大,内存又被称为主存,其作用是存放CPU中的运算数据,以及与硬盘等外部存储设备交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到主存中进行运算,当运算完成后CPU再将结果传送出来,主存的运行也决定了计算机的稳定运行。

内存的物理结构
必备常识之内存
内存的内部是由各种IC电路组成的,它的种类很庞大,但是其主要分为三种存储器

  • 随机存储器(RAM) :内存中最重要的一种,表示既可以从中读取数据,也可以写入数据。当机器关闭时,内存中的信息会丢失
  • 只读存储器(ROM) : ROM 一般只能用于数据的读取,不能写入数据,但是当机器停电时,这些数据不会丢失
  • 高速缓存(Cache) : Cache 也是我们经常见到的,它分为一级缓存(L1 Cache)、二级缓存(L2 Cache)和三级缓存(L3Cache),它位于内存和CPU之间,是一个读写速度比内存更快的存储器。当CPU向内存写入数据时,这些数据也会被写入高速缓存中。当CPU需要读取数据时,会直接从高速缓存中直接读取,如需要的数据在Cache中没有,CPU会再去读取内存中的数据。

内存IC是一个完整的结构,它内部也有电源、地址信号、数据信号、控制信号和用于寻址的IC引脚来进行数据的读写。下面是一个虚拟的IC引脚示意图:
必备常识之内存
图中VCC和GND表示电源,AO - A9是地址信号的引脚,DO - D7表示的是控制信号、RD和WR都是好控制信号,将电源连接到VCC和GND后,就可以对其他引脚传递0和1的信号,大多数情况下,+5V表示1, OV表示0。
我们都知道内存是用来存储数据,那么这个内存IC中能存储多少数据呢? DO - D7表示的是数据信号,也就是说,一次可以输入输出8 bit= 1 byte 的数据。A0 - A9是地址信号共十个,表示可以指定00000 0000- 11111 1111共2的10次方= 1024个地址 。每个地址都会存放1 byte 的数据,因此我们可以得出内存IC的容量就是1 KB。
如果我们使用的是512 MB的内存,这就相当于是512000 (512 * 1000) 个 内存IC。 当然,一台计算机不太可能有这么多个内存IC,但是,通常情况下,一个内存IC会有更多的引脚,也就能存储更多数据。

内存的读写过程
让我们把关注点放在内存IC对数据的读写过程上来吧!我们来看一个对内存IC进行数据写入和读取的模型:
必备常识之内存
假设我们要向内存IC中写入1byte的数据的话,它的过程是这样的:

  • 首先给VCC接通+5V的电源,给GND接通0V的电源,使用AO-A9来指定数据的存储场所,然后再把数据的值输入给DO-D7的数据信号,并把WR(write)的值置为1,执行完这些操作后,即可以向内存IC写入数据
  • 读取数据时,只需要通过AO-A9的地址信号指定数据的存储场所,然后再将RD的值置为1即可
  • 图中的RD和WR又被称为控制信号。其中当WR和RD都为0时,无法进行写入和读取操作

内存的现实模型
内存的模型很像我们生活的楼房。在这个楼房中,1层可以存储一个字节的数据, 楼层号就是地址,下面是内存和楼层整合的模型图:
必备常识之内存
程序中的数据不仅只有数值,还有数据类型的概念,从内存上来看,就是占用内存大小。即使物理上强制以1个字节为单位来逐一读写数据的内存,在程序中,通过指定其数据类型,也能实现以特定字节数为单位来进行读写。
下面是一个以特定字节数为例来读写指令字节的程序的示例:
必备常识之内存
我们分别声明了三个变量a, b, c ,并给每个变量赋 上了相同的123,这三个变量表示内存的特定区域。通过变量,即使不指定物理地址,也可以直接完成读写操作,操作系统会自动为变量分配内存地址。
这三个变量分别表示1个字节长度的char, 2个字节长度的short,表示4个字节的long。因此,虽然数据都表示的是123,但是其存储时所占的内存大小是不一样的。如下所示:
必备常识之内存
这里的123都没有超过每个类型的最大长度,所以short和long类型为所占用的其他内存空间分配的数值是0,这里我们采用的是低字节序列的方式存储
必备常识之内存
内存的使用
指针是C语言非常重要的特征,指针也是一种变量, 只不过它所表示的不是数据的值,而是内存的地址。通过使用指针,可以对任意内存地址的数据进行读写。
在了解指针读写的过程前,需要先了解如何定义一个指针,和普通的变量不同,在定义指针时,会在变量名前加一个*号。 例如我们可以用指针定义如下的变量:
必备常识之内存
实际上,这些数据表示的是从内存中一次读取的字节数,比如d e f的值都为100,那么使用char 类型时就能够从内存中读写1 byte的数据,使用short类型就能够从内存读写2字节的数据,使用long就能够读写4字节的数据,下面是一个完整的类型字节表:
必备常识之内存
我们可以用图来描述一下这个读写过程:
必备常识之内存
数组是内存的实现
数组是指多个相同的数据类型在内存中连续排列的一种形式。作为数组元素的各个数据会通过下标编号来区分,这个编号也叫做索引。
首先来认识一下数组,我们还是用char、short、 long 三种元素来定义数组,数组的元素用[value] 扩起来,里面的值代表的是数组的长度,就像下面的定义:
必备常识之内存
数组定义的数据类型,也表示一次能够读写的内存大小,char 、short 、long 分别以1、2、4个字节为例进行内存的读写。
数组是内存的实现,数组和内存的物理结构完全一致, 尤其是在读写1个字节的时候,当字节数超过1时,只能通过逐个字节来读取,下面是内存的读写过程:
必备常识之内存
还没完,下篇文章会说一说栈和队列。