【C/C++】结合计算机组成原理看C语言指针

1. 指针长度与什么有关

先由一个问题引入,C语言指针占多少字节?

如果上过大一C语言课程,那你肯定脱口而出:4个字节。但是你可能忘了老师很早说的一个前提,在32位处理器(或操作系统/编译环境)中,才是这个答案。

实际上在64位处理器(或操作系统/编译环境)中,指针的长度是占8个字节。而在更早的16位、8位计算机中,这个答案可能是2字节、1字节。

可以看到,指针的长度,总是与处理器的处理位数正相关,那么C语言指针的长度,到底是有什么决定的呢?

1.1 ”X位处理器“的含义(机器字长)

我们常常听到32位/64位处理器的说法,这是什么意思?

CPU内有三大总线(控制总线、地址总线、数据总线)

操作内存简化过程:1. CPU通过地址总线,在内存中找到目的区域的位置;2. 通过控制总线告之读/写操作;3. 从缓存中读数写入内存(写操作)或 从内存中读书写入缓存(读操作)

所以XX位处理器是指,CPU在单位时间内一次能处理(处理、传输、暂时存储)的二进制数的位数

例如32位处理器,一次能处理32个二进制位(32bits)信息。即三大总线带宽是32位(32根线捆成一捆,每根线同时只能传输一位,32根便能同时传32位信息)

1.2 内存须知

内存模型

内存中,每个内存单元都是8位(8bits=1B)的,所以把内存看成是一张二维表,它有n行8列。

像这样的每一行称为一个内存单元。(当然在计算机的发展历史上,出现过其他数目的内存单元,但是现在的通用计算机内存单元的可用位数都是8位(可能会加入校验位,但是可用的就是8位))

每个内存单元(即每一行)都有一个地址,例如容量4GB(一行有8位,为1B,有4G=232行)的内存条有34359738368位(4GB*8位)(这个二维表是232行8列)

为了给每一行编号,需要从000…000(32个0)编到111…111(32个1)。

1.3 指针长度

以32位计算机为例

32位处理器,一次能处理32个二进制位(32bits),即寻找地址时的地址总线需要32根,这样传输一遍就能找到准确地址(寻址能力为32位)。

所以32位处理器的指针为4字节(也就是32bits),能准确找最多232个地址不含糊,因此32位处理器最多也就支持4GB内存(有232个地址),再大就不行了。

同理,64位处理器的指针长度为8位。

总结:机器的字长就是指针的字长

1.4 int类型的字长

使用sizeof(int)查看int类型的字长

int类型的字长,同指针的字长,也就是机器的字长

即在32位的计算机里,int就是4个字节;在64位的计算机里,int就是8个字节。

2. 定义指针时为什么要用某个数据类型约束

既然处理器的处理位数是个定值,那么指针的长度就确定了,但是在定义时,我们是这样做的

// 指向整型的指针
int * P1 = NULL;
// 指向浮点类型的指针
float * P2 = NULL;
// 指向字符类型的指针
char * P3 = NULL;
// ……

可以看到,我们在定义是总是用int、float、char…这样的变量类型来约束指针。但是明明指针就是存放了一个地址(数),且长度是固定的(比如32位编译环境下是4字节),这么做是为什么呢?

这么做是为了移动指针的时候更方便。比如遍历一个整型数组时,定义一个指向整型的p1来指向各个元素,p1相当于同时指多个内存单元,此时用++p1就可以方便地向后移动一个元素了(指针加上一个整数,意味着向后挪动,不是数值相加),如果不以这种方式定义指针的话,就要明确指明向后移动多少个内存单元,例如32位处理器int类型长度为4字节,则往后移动一个元素,就要写成p1+=4(假设这里p1每次只指一个内存单元)

发布了11 篇原创文章 · 获赞 54 · 访问量 661

猜你喜欢

转载自blog.csdn.net/qq_33973359/article/details/105497294