从计算机组成原理寻址方式参悟指针的本质
一:简要概括计算机寻址系统
1.页表
页表是操作系统为每个进程维护的一张“映射表”,用来将虚拟地址映射到物理地址。
虚拟内存地址:
虚拟内存是一种由操作系统提供的机制,它给每个进程一个独立的、连续的“假象”内存空间,而这实际上不一定真实存在于物理内存中。一个进程的数据地址在虚拟内存上的存储地址是连续的,但是通过各种算法将这些地址映射到我物理内存上就未必是连续的。
物理内存地址:
物理地址是指内存条(RAM)中某个实际存储单元的地址,是 CPU 最终用来访问真实硬件内存位置的地址。
它是和计算机硬件一一对应的“实打实的地址”
虚拟内存和物理内存基本结构总结
ps:一个页框通常存储一整块数据区域,这取决于它的大小。
一个页框的大小是固定的(比如 4KB),而内存中每个“地址”对应的是一个字节(Byte),
所以一个页框实际上包含的“地址数量”就是它的字节数。
在现代计算机中,存储中的每个“地址”都是固定大小的:每个地址对应 1 字节(Byte)的存储单元。这个“1 字节”为单位是固定的,和机器的字长无关。
在现代计算机中,存储中的每个“地址”都是固定大小的,都是1byte,它们的差距仅仅是寻址的范围不同
每个地址对应 1 字节(Byte)的存储单元。这个“1 字节”为单位是固定的,和机器的字长无关。
2.直接寻址和间接寻址概述
直接寻址
如果系统开启了虚拟内存(即启用了分页机制),那么所有对内存的寻址——包括“直接寻址”——都必须经过页表映射才能访问物理内存。
所以直接寻址就是侧重如何从(物理)地址找到地址下的数据,然后cpu会直接拿着这个地址访问物理内存
所以一般来讲,直接寻址的地址在物理内存上是连续的。
直接寻址的应用之一就是数组。
间接寻址
间接寻址侧重的是如何通过虚拟地址找到物理地址 如图
如图 cpu通过虚拟内存地址按照一定算法让他们指向对应的物理内存地址
二.什么是指针
指针(Pointer)
是存储另一个变量地址的变量。
换句话说,指针里面存的是“内存地址”,而不是具体的数据。
int a = 10;
int *p = &a; // p 存的是变量 a 的地址
printf("%d", *p); // 通过指针访问 a 的值,输出 10
如上代码 指针是用于存储一个变量的地址的
地址之下才是具体存储的数据
三. 二者之间的联系
所以,我们可以直接读出结论,指针就是虚拟地址在C语言中的具象化。
指针变量中存储的地址值,实际上就是虚拟地址的具体数值(即虚拟地址的“具象化”)!
也就是说:
-
当你写
int *p = &x;
,p
存的其实是x
在虚拟地址空间中的地址。 -
程序操作指针时,实际上是在操作虚拟地址。
-
CPU 和操作系统把这个虚拟地址再通过页表转换成物理内存地址。
-
int x = 42; int *p = &x;
所以有很多问题便可以说的清了概念 说明 指针 程序中存储地址的变量,是虚拟地址的“载体” 虚拟地址 操作系统给进程分配的地址空间,程序看到的所有地址都是虚拟地址 - 数组存储空间是连续的,因为它采用的是直接寻址,理论上不存在指针这一结构
- 链表物理存储空间是不连续的,因为它采用的是间接寻址,需要使用指针这一结构去一一映射到物理内存上
- 这也说明了为什么在数据结构中为什么数组的增删查改不灵活但是却不需要遍历整个容器便可以直接获得所需元素
- 为什么链表虽然结构灵活增删查改不需要动其他元素也可以完成但是每次要获取指定元素却需要遍历整个结构