第一节 —— 从深层剖析指针(让你不再害怕指针)

1. 内存和地址(指针)

1.1内存

生活案例

你住在万国大酒店的3楼342房间,你告知你的朋友来万国大酒店耍耍,但是你并没告诉他具体位置。你的朋友只能挨个房间找,这样的效率很低。
但如果你告诉了他具体位置,他就能很快找到你的位置,提升效率。

那么对照到计算机上,又是怎么样的呢?

我们知道计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那这些内存空间如何高效的管理呢?
内存划分为⼀个个的内存单元,并且每个内存单元的大小取1个字节。
在这里插入图片描述


每个内存单元(1字节对应8比特位)都有对应的编号,cpu就可以快速找到一个内存空间。

所以我们可以理解为:内存单元的编号 = 地址 = 指针

1.2知识引入— —如何理解编制

那么,cpu是如何访问内存中的某个字节空间呢?
其实,硬件设计的时候地址编号已经设计好了
在这里插入图片描述

地址总线:若是32位机器则有32根地址总线,每根线只有两态,表示0,1【电脉冲有无】,那么⼀根线,就能表示2种含义,2根线就能表示4种含义,依次类推。32根地址线,就能表示2^32种含义,每⼀种含义都代表⼀个地址。

cpu访问内存:若创建了一个变量a,那么会向内存申请空间,当cpu要访问内存时,需要先通过控制总线读取内存中对应的编址,再通过数据总线传输回来

2. 指针变量和地址

2.1&和*的引入

& --> 取地址操作符:拿到一个元素的地址
* --> 解引用操作符:通过存放的地址,找到指向的空间

如何拆解指针

在这里插入图片描述


指针又可以帮助我们实现什么呢?通过 指针改变变量的值

在这里插入图片描述
疑问:如果目的只是改变a的值,那么为何不直接改变a的值,而要通过指针大费周章地交给p来操作呢?
其实这里是把a的修改交给了pa来操作,这样对a的修改,就多了一种的途径,写代码就会更加灵活,后期慢慢就能理解了。(有种老大哥把事情交给小弟做的感觉)

2.2指针变量的大小

32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产生的2进制序列当做一个地址一个地址就是32个bit位,需要4个字节才能存储。
同理,64位机器需要8个字节才能存储。

为了验证我们的想法,我们可以写以下代码
在这里插入图片描述
在这里插入图片描述

3. 指针变量类型的意义

指针变量的大小和类型无关,只要是指针变量,在同一个平台下,大小都是一
样的,那为什么还要有各种各样的指针类型呢?其实指针类型是有特殊意义的

3.1指针的解引用

在这里插入图片描述

调试我们可以看到,代码1会将n的4个字节全部改为0,但是代码2只是将n的第⼀个字节改为0。

结论指针的类型决定了,对指针解引用的时候有多大的权限(⼀次能操作几个字节)。

比如:char* 的指针解引用就只能访问一个字节,
int* 的指针的解引用就能访问四个字节。

3.2指针±整数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以发现对pa+1一次能跳过四个字节,而对pc+1一次只能跳过一个字节。

结论指针的类型决定了指针向前或者向后⾛⼀步有多⼤(距离)。

比如:char* 的指针解引用就只能跳过一个字节,
int* 的指针的解引用就能跳过四个字节。

3.3void*指针

⼀种特殊的类型是void * 类型的,可以理解为无具体类型的指针
(或者叫泛型指针),这种类型的指针可以用来接受任意类型地址
在这里插入图片描述

局限性

想通过*void指向的值并不能被改变,无法直接进行指针运算
在这里插入图片描述

4. const修饰指针

变量是可以修改的,但如果我们希望⼀个变量加上⼀些限制,不能被修改,怎么做呢?就需要使用到const

4.1const修饰变量

const修饰的变量是常量还是变量?
C语言中,这里的n是常变量,num的本质还是变量,因为有const修饰,编译器在语法上不允许修改这个变量
C++中,这里的n就是常量

C语言环境中

在这里插入图片描述

C++环境中

我们知道数组里的值必须为常量,而这里为何可以放变量n呢?这是由于n被const修饰而不能被修改,n就为常量了,这是在C++中规定的。
在这里插入图片描述

漏洞

我们发现不能直接改变这个被const修饰的值,那是否有别的办法间接改变这个变量的值呢?
答案是肯定的,我们可以通过指针的方式改变变量的值(相当于你这个老大不想做,把这件事交给你的小弟做)。
在这里插入图片描述

4.2const修饰指针变量

⼀般来讲const修饰指针变量,可以放在*的左边,也可以放在*的右边,意义是不⼀样的

const修饰在*左边

当const修饰的是指针指向的内容(*p),不能通过指针来改变。但是指针变量本⾝的内容可变。
在这里插入图片描述
在这里插入图片描述

const修饰在*右边

const如果放在*的右边,修饰的是指针变量本⾝,指针变量的内容不能修改。但是指针指
向的内容,可以通过指针改变。
在这里插入图片描述
在这里插入图片描述

结论

1.const如果放在*的左边,修饰的是指针指向的内容,保证指针
指向的内容不能通过指针来改变。但是指针变量本⾝的内容可变。

2.const如果放在*的右边,修饰的是指针变量本⾝,保证了指针
变量的内容不能修改,但是指针指向的内容,可以通过指针改变。

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值