OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6091|回复: 1

来聊一下,指针到底是何方神圣呢?

[复制链接]

1107

主题

1118

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4615
金钱
4615
注册时间
2019-5-8
在线时间
1218 小时
发表于 2021-11-4 17:46:20 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2021-11-5 10:36 编辑

以下文章摘自微信公众号——开源电子网《来聊一下,指针到底是何方神圣呢?》
更多技术文章,请扫下方二维码关注

开源电子网,扫码2222222.png





什么是指针

    指针你真正了解吗?那么你懂得计算机内存是如何存储吗,如果你真正了解指针到底是是什么,那么你就会懂得计算机内存是如何存储的。

    首先了解指针之前,我们必须了解计算机内存是如何存储的,一般的32位计算机把内存分割为字节,一般32位的机器int类型为32比特,也就是4字节,一字节有8bit数据,这个必须知道的知识点,如以下图所示:

1.jpg

    上图可知:一个字节8bit的数据,所以计算机为了区分内存的每一个字节,那么计算器给它们进行排号,而这些号就是地址,例如学校的宿舍,每一间的宿舍住了八个人,宿舍必定有一个宿舍号,所以舍管阿姨会对宿舍号进行查找的某宿舍人员的原理类似。

2.jpg

    上图可知,一般来说int型变量有4字节,所以每一个地址偏移4个字节,如果指针P指向0x20000004地址,那么该地址存储的值就是0x82。

C语言指针是什么

    上面我们已经了解计算机内存是如何存储以及如何读取地址的值,显然小编是举32位的计算机就是为了方便我们学习MCU,因为MUC大部分也是32位的。

    C语言指针可以简化一些C编程任务执行的任务,例如动态内存分配,如果没有指针那么无法执行的,所以成为C程序员或者嵌入式工程师,学习指针很有必要的。

    数据在内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量。在学习C语言时候,变量都有一个内存位置,那么它们可以使用“&”运算符访问地址,表示它在内存中的一个地址。如以下源码所示:

3.png

    串口调式助手输出他们的打印信息,如以下所示:、

4.png    


我们怎么理解上述输出的信息呢?,可以使用示意图来解析上述的信息,如图所示:

5.jpg

总结


① 变量名、函数名、字符串名和数组名在本质上是一样的,它们都是地址的助记符
②“&”运算符访问地址
③ *ip_variate就是读取指针变量存储的地址对应的值(20000784的地址的值10)
④ ip_variate读取指针变量存储的地址

小知识

    如果程序被编译和链接后,使用* ip_variate 的话,要先通过地址20000780取得变量ip_variate 本身的值,这个值是变量lv_variate 的地址,然后再通过这个值取得变量lv_variate 的数据,前后共有两次步奏;而使用lv_variate 的话,可以通过地址20000784直接取得它的数据,只需要一步运算。

可以这样说,使用指针是间接获取数据,使用变量名是直接获取数据。

什么是二级指针

    上面我们以及理解什么是指针以及一级指针的操作,如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。

    二级指针是指向一级指针的指针。二级指针指向一级指针,也就是二级指针中存储的是一级指针的内存地址。

二级指针的使用

6.png

执行结果

7.png

    我们怎么理解上述输出的信息呢?,可以使用示意图来解析上述的信息,如图所示:
8.jpg

总结

① 变量名、函数名、字符串名和数组名在本质上是一样的,它们都是地址的助记符

②“&”运算符访问地址

③ q读取指针变量存储的地址(0x20000784)

④ *q读取指针变量存储的地址的对应的值(就是一级指针变量存储的地址(0x20000788))

⑤ **q读取指针变量存储的地址的对应的值的对应地址的值(就是一级指针变量存储的地址(0x20000788)对应的值(10))

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

79

主题

395

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1754
金钱
1754
注册时间
2015-9-21
在线时间
542 小时
发表于 2021-11-4 21:09:17 | 显示全部楼层
看到这里,也许你会觉得,这么简单的东西还用你来说吗?的确,对于p与&p来说,99%的人都能在0.1秒内脱口而出谁是指针,谁是地址,但是,又有多少人在使用指针的过程中能够始终如一毫不动摇地遵循这两个概念呢?不少人使用指针的时候就会自觉或不自觉地把指针和地址两个概念混淆得一塌糊涂了,数组名的滥用就是一个活生生的例子。这一点甚至连一些经典著作也没能避免。

    不过也不能全怪你自己,笔者认为某些国内教材应该承担最大的责任。这些教材一开始就没有给读者好好地分清指针与地址的区别,相反还在讲述的过程中有意无意地混用这两个概念。更有甚者,甚至在书中明言指针就是地址!说这话的家伙最应该在C语言这个地图上抹掉,呵呵。两个月前我在购书中心随手翻开了某个作者主编的一本被冠以国家“十五”规划重点研究项目的书,书里就是这么写的。当时笔者就感慨:不知道又要有多少人的思想被这家伙“强奸”了。

实际上,地址这个东西,本来就是一种基本数据类型,本应该在介绍整数、浮点、字符等基本类型的时候把地址显式地放在一起讨论,这样在后面介绍指针与数组的时候就能避免许多误解。可惜不少教材或者根本没有谈及,或者就算提起这个类型也用了指针类型这个字眼。这就错了,指针不是类型,真正的类型是地址,指针只是存储地址这种数据类型的变量!打个比方,对于

int i=10;

10是整数,而i是存储整数的变量,指针就好比这个i,地址就好比那个10。指针能够进行加减法,原因并不是因为它是指针,加减法则不是属于指针这种变量的,而是地址这种数据类型的本能,正是因为地址具有加减的能力,所以才使指针作为存放地址的变量能够进行加减运算。这跟整数变量因为整数能够进行加减乘除因而它也能进行加减乘除一个道理。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-10-4 02:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表