[深入浅出C语言]初探指针——认识指针和编址

78 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

前言

        学习C语言,不得不学到的就是指针,甚至可以这么说:指针是C语言的精髓之所在。

        本文就来分享一波作者的C指针学习见解与心得。本篇属于初阶第一篇,主要讲解指针是什么和如何编址。后续还有初阶的其他内容以及进阶内容,可以期待一下。

        笔者水平有限,难免存在纰漏,欢迎指正交流。

指针是什么

引入

        首先,这里先给出一个概念:指针就是地址,口语中说的指针通常指的是指针变量。那何谓地址?顾名思义,其实很简单,正如现实生活中我们每个人的住处都对应一个地址一样,内存中的一块一块空间(以字节为单位)都被人为地分配了数字编号进行唯一标识,这一串串的数字编号便是内存空间的地址。

image.png

举个例子

        常用的例子就是住户的门牌号,小区里的住楼都是以户为单位的,每一户的构造由基本相同,如果没有划分编号的话很有可能就找不到想要找的住户,毕竟家家户户从门外看都是一样的。一旦根据一定依据,比如说这栋楼是A区的,每层的住户给上对应楼层号,再按一定顺序分配号码,像是A213,就是A区楼2楼第13位住户。这样一来想要访问和管理这么多住户中特定的一户就容易的多了。

image.png

        为何每家住户都要有门牌号呢?结论:提高查找效率和准确度。

        类比到计算机中

        CPU在内存中寻址的基本单位是多大?——字节

        在32位机器下,最多能够识别多大的物理内存?——2^32字节

        既然CPU寻址按照字节寻址,但是内存又很大,所以,内存可以看做众多字节的集合

        其中,每个内存字节空间,相当于一家住户,字节空间里面能放8个比特位,就好比住入了8个人,每个人是一个比特位。

        每家住户都有门牌号就等价于每个字节空间对应的地址,即该空间对应的指针。

        那么,为何要存在指针呢?为了CPU寻址的效率。如果没有,该怎么找在字节空间中的数据呢?只能是按顺序遍历,那样的话想想效率就低的不行。

关于编址的理解

        经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。

存储空间的单位有:

bit

byte

kb

mb

gb

...

        而各类型的变量的大小最小1byte,最大也不过8byte,如果用bit为内存单元分配地址的话太浪费地址了,内存就会很小,而要是用kb之类的为内存单元分配地址的话太浪费空间了,所以用byte是相对更合适的。

如何编址

        何谓编址?即地址的编制,先前讲过,地址是一串标识用的数字,那这串数字到底是如何规定的呢?

        地址本身是由硬件电路产生的一串二进制序列,用来唯一标识一块内存空间(以字节为单位)。

        对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0),把电信号转换为数字信号。

        那么32根地址线产生的地址就会是

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

00000000 00000000 00000000 00000002

...

11111111 11111111 11111111 11111111

        这里就有2^32个地址。

        每个地址标识一个字节,经过换算:

(2^32Byte == 2^32/1024KB ==2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB)

        那我们就可以给4G的空间进行编址,每一个字节的空间给它分配上一个地址。

        在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,指针变量是用来存储指针的变量,所以一个指针变量的大小就应该是4个字节。

        而在64位机器上,有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。

深入理解编址

        首先,必须理解,计算机内是有很多的硬件单元,而硬件单元是要互相协同工作的。所谓的协同,至少相互之间要能够进行数据传递。

        但是硬件与硬件之间是互相独立的,那么如何通信呢?答案很简单,用"线"连起来。

        而CPU和内存之间也是有大量的数据交互的,所以,两者必须也用线连起来。

        不过,我们今天关心一组线,叫做地址总线。

        CPU访问内存中的某个字节空间,必须知道这个字节空间在内存的什么位置,而因为内存中字节很多,如果直接遍历查找效率会很低很低,所以需要给内存进行编址(就如同宿舍很多,需要给宿舍编号一样),以此来提高查找效率,利于管理内存空间。

        计算机中的编址,并不是把每个字节的在内存中的具体位置记录下来,而是通过硬件设计完成的,本质就是生成若干组编码分配给一个一个的空间。

        举个例子:钢琴、吉他上面没有写上“都瑞咪发嗦啦”这样的信息,但演奏者照样能够准确找到每一个琴弦的每一个位置,这是为何?因为制造商已经在乐器硬件层面上设计好了,并且所有的演奏者都知道。本质是一种约定出来的共识。

        硬件编址也是如此

        我们可以简单理解,32位机器有32根地址总线,每根线只有两态,表示0或1【电脉冲有无】,那么一根线,就能表示2种含义,2根线就能表示4种含义,通过简单的排列组合,以此类推,32根地址线,就能表示2^32中含义,每一种含义都代表一个地址。

        地址信息被下达给内存,在内存内部,就可以找到该地址对应的数据,将数据在通过数据总线传入CPU内寄存器。         

image.png


以上就是本文的全部内容了,感谢观看,你的支持就是对我最大的鼓励~

u=368843430,1038707705&fm=253&fmt=auto&app=138&f=JPEG.webp