目录:
一、内存和地址
(1)内存地址
(2)如何理解编址
二、指针变量和地址
(1)指针变量与操作符
(2)指针变量类型拆解和大小
三、指针变量的类型意义
(1)指针+-整数
(2)void* 指针
正文
一、内存和地址
现实生活中,内存好比一栋大楼,大楼分为多个房间,每个房间都对应着一个门牌号,而这个门牌号就象征着地址,当我们要找朋友时,知道他在哪一栋楼,第几间房才能找到他
在电脑中,内存其实也划分为一个个内存单元,每个内存单元为1个字节,有对应的单元编号,编号就是地址,在C中又给它取名叫指针
内存单元的编号 == 地址 == 指针 三者等价
1.1 如何理解编址
计算机中有很多的硬件单元,例如:CPU、内存、存储设备、显卡、主板等,它们之间都是通过“线”建立联系,相互协作。
CPU要从内存中获取数据,内存又划分为一个个内存单元,电脑硬件电路通过内存单元编址,自动快速找到目标数据。
地址总线在32位机器上有32根地址线(64位机器则有64根)每根线只有两个态0、1(称为电脉冲有无)那么 ⼀根线就能表示2种含义,2根线就能表⽰4种含义,依次类推。32根地址线,就能表示2^32种含义,每⼀种含义都代表⼀个地址。
这些单元编址需要存储起来吗?答案是:不用。
这些编址并不是我们人为编的,由电脑硬件电路设计。我们只要给出要找数据的地址编号,硬件电路会自动找到对应的内存单元。就像钢琴上每个键都有对应的音符,这些音符早就通过某种规则设计好了,并不需要特地在钢琴上标记,只要演奏者按一定的规律弹奏即可弹出乐曲。
硬件之间如何协同操作?
CPU读数据:
控制总线发出读的信号(R),CPU将对应数据所在的地址通过地址总线转为二进制传递给内存,内存通过传过来的地址找到数据后再通过数据总线读入CPU中。
内存写数据:
控制总线发出写的信号(W),CPU将要写入数据所在的地址通过地址总线转为二进制传递给内存,当内存找到空间后,CPU在通过数据总线将数据传给内存。
二、指针变量和地址
2.1 取地址操作符(&)
在C语言中,创建变量的本质是向内存申请空间,创建一个int 型变量a,在内存中会分配4个字节的空间给a,其中每个字节都有地址,当我们要取出a的地址时,需写成&a(&为取地址符号),同时取出的是a所占4个字节中地址最小的字节的地址。
2.2 指针变量
取出a的地址需要一个变量将它存起来,假设这个变量是pa,那么pa只有是个指针变量才能存放地址;a是int 类型所以也要用int 型的指针变量存储,应写成:int* pa = &a;
可知,指针变量是用来存放地址的,存放在指针变量中的值理解为地址
指针 == 指针变量,通常直接叫指针,其实指的就是指针变量。
2.3 解引用操作符(*)
把a地址存入指针变量中,当想通过指针变量所存放的地址找到a,并修改a的值时需要用到解引用操作符
*pa表示通过pa中存放的地址找到a,*pa就是等于a,改动*pa的值等于改变a的值
想改变a的值不止一种方式,通过指针改变a的值只是其中一种方式。
2.3 指针变量的拆解
我们看到pa的类型是int*,其中*仅仅只是表明pa是个指针变量(当你要让某个变量成为指针变量只需前面加颗*)int表示指针变量*pa指向的是整型类型的对象
若a 是字符型变量,对应的指针变量为:char* pa
2.4 指针变量的大小
地址大小是以字节为单位(1个字节等于8个bit位)指针变量中存放的是地址,问指针大小实则问地址大小
在32位机器上有32根地址总线,把32根地址总线产生的二进制序列当成地址就有32个bit位,需要4个字节才能存放的下,所以地址为4字节
在64位机器上有64根地址总线,把64根地址总线产生的二进制序列当成地址就有64个bit位,需要8个字节才能存放的下,所以地址为8字节
可得:指针变量的大小与类型无关,与环境有关
三、指针变量的类型意义
既然指针在同一平台下大小都一样,那还需要不同类型干嘛,全部用int 类型不行吗? 不行!
3.1 指针+-整数
先看一段代码的变化:
结果:
可以看出:字符类型的指针+1跳过1个字节,整型指针+1跳过4个字节
由此可得:类型的不同影响指针向前或向后走一步的大小(距离)
3.2 void* 指针
泛型指针,表示无特定类型指针
当不知道用户传过来的地址是什么类型时可用void*接收,void*类型不可进行指针+-整数运算和解引用
void*最常用于函数参数部分,⽤来接收不同类型数据的地址,后续会详讲,敬请期待.......
未完待续