指针

对于学习c/c++的同学,指针是不可避免的而且也是必须掌握的

指针可以说是c/c++中很精华的一个东西

如果对于指针不了解那么这门编程语言可以是说你是不合格的

好,首先我们弄清几个问题

1.c/c++为什么要有指针这东西?

2.指针到底是个什么东西?

3.指针到底有什么用?

4.指针到底怎么用?

 

1.c/c++为什么要有指针这东西?

其中涉及一些硬件的东西,计算机组成原理。了解一下就好了,我也不是很懂。百度的

原文https://blog.csdn.net/dangbai01_/article/details/79501037

早期的CPU(也许并没有真正的实现)并不如今天的强大,
内存读写的指令可能只有:
“从*常数*0x1234地址处读入1字节到寄存器a”,
或者“把寄存器b的值写入*常数*地址0x5678这个地方”。
那个时候没有变量这一说,所有的内存读写都得指定好常数,也就是得把具体的数字(也称为字面量,literal)写死在程序里。
换言之,你如果想清空100字节的内存,而每条指令只能对内存中某一个字节进行写入,那就得写100条指令。随着要处理的数据的膨胀,程序也得跟着膨胀,而这是不可接受的。


流程跳转

为了解决清空大量内存的问题,人们发明了控制流程的指令
比如“如果寄存器c的值为0,则略过下一条指令”和“无条件跳转到首地址为0x9012”的地方,从那个地方继续运行”。
注意,指令本身也是编码成字节存在内存里的,这就是冯诺伊曼机器最优雅的地方。这时候我们可以写出循环了



自修改程序
问题并没有解决,因为就算有了循环,整个程序还是只能写常量,所以如果想要对不同的内存块清零,只能写不同的指令,对应常量值写指令。
但是人是很聪明的。
利用“指令本身也是编码成字节存在内存里”这个特征,我们可以通过修改内存来修改指令,继而修改行为。

举例来说,在0x3454处存了一条指令,这条指令叫做“把0x5678开始的一字节清零”。
比方说这条指令占用了三个字节,第一个字节告诉CPU这是一条清零指令,后两个字节(0x3455和0x3456)存了一个表示地址的整数,告诉CPU到底要把哪个字节清零。显然,这个整数会和0x5678有关,而且大多情况就是0x5678。
现在,要是CPU在某处执行了一句“把起始地址为0x3455的那个2字节数自增1”,那实际上0x3454处的指令就变成了“把0x5679开始的一字节清零”!
看到希望了么,我们可以写一个指令,然后不断修改这个指令,再加上流程控制的指令产生一个循环,就能用一段固定长度(注意,代码内容随着执行并不固定)的代码清零任意指定的一段内存块!
这叫做“自修改程序”。



间接寻址
后来的事情就很简单了。编写这种自修改程序极容易出错,因为稍微改错一个地方指令就全改乱了,比如在上例中如果把0x3454中的数字给改了,就完全变成了另一条指令,
所以人们再次发明新的工具,叫间接寻址。
所以有了这样的指令“把寄存器a存的数字当成地址,取出该地址处的字节放到寄存器b里”和“把寄存器a存的数字当成地址,把寄存器b的字节写入到该地址处”。
回到自修改程序的那个例子里,我们可以把“把0x5678开始的一字节清零”换成:

“把寄存器b设为0”
“把0x5678这个数字写到0x1234处”
“读入0x1234的数字到寄存器a”
“把寄存器a存的数字(此处即0x5678)当成地址,把寄存器b(此处为0)的字节写入到该地址处”
这样实现虽然看起来费事,但是总算得到了等价的功能。另外,我们以后只需要读写0x1234这个内存就能达到改变行为的目的,而不要冒险去修改指令本身了。换言之,指令本身被固化,其行为更加稳定

今天,代码虽然也在内存里,也编码成了一个个字节,但是一般不和数据放在一起,而且一般执行的时候是只读的。
假设程序员无限聪明(当然这种好事从来就没有发生过:),写的代码从来不出错,那么间接寻址是没有必要的,因为直接写自修改程序就行了。间接寻址没有增加任何新的功能,这点不像跳转指令。

指针
哦,现在解释指针就很简单了,指针就是间接寻址例子里面那个0x1234的内存块。它存了一片地址,而指针解引用(比如*p)就对应的是间接寻址读写的指令了。
所以说到最后,“为什么要有指针的”就可以化成“为什么要有间接寻址”,问题基本等价于“为什么不直接使用自修改程序”了。
希望我说得比较明白。 
View Code

说人话:

为了解决清空大量内存的问题,而设计的一个东西。反正能提高执行效率

 

2.指针到底是个什么东西?

根据1的解释

哦,现在解释指针就很简单了,指针就是间接寻址例子里面那个0x1234的内存块它存了一片地址,而指针解引用(比如*p)就对应的是间接寻址读写的指令了

 

3.指针到底有什么用?

这两个地方我觉得说的很好很详细了

传送门1:https://blog.csdn.net/IOT_SONG/article/details/51492132

 传送门2:https://blog.csdn.net/zhanshen112/article/details/80265830

指针用处总结:

(1)可以提高程序的编译效率和执行速度,使程序更加简洁。

(2)通过指针被调用函数可以向调用函数处返回除正常的返回值之外的其他数据,从而实现两者间的双向通信。

(3)利用指针可以实现动态内存分配。

(4)指针还用于表示和实现各种复杂的数据结构,从而为编写出更加高质量的程序奠定基础。

(5)利用指针可以直接操纵内存地址,从而可以完成和汇编语言类似的工作。

 

当然这也有不好的地方

就是你必须很清楚指针在每个地方的用处,和明确怎么用。不然会存在一些很难查找的错误

 

4.指针到底怎么用?

 用法很多啊,自己去看看吧。

posted @ 2019-09-22 13:25  ChunhaoMo  阅读(178)  评论(0编辑  收藏  举报