指针重点总结
C/C++指针踩坑历险记-常量指针-const ptr *,指针常量ptr * const,引用,指针传参,指针修改,指针指向的值修改等问题
好久没写C语言了,不过一直用C++在刷题,遇到指针总有些发憷?初学指针的时候觉得指针好难,其实搞清指针的重要几个概念,指针就不难~对指针一些重点知识进行一个总结。
指针初体验
我们知道指针本质上就是一个存放地址的变量(该变量存放地址,一串你看不懂的数字)。比如
1 | int a = 3; |
下面举个例子,直观地展示一下ptr的值
1 |
|
输出结果
通过设置断点查看程序执行过程,也可以查看ptr存放的到底是什么
你现在只需要知道指针就是指向一个内存块的地址,本质上就是一个变量。
对指针有了直观的认识之后,你肯定会想,要一个内存单元的地址有什么用呢?这个地址(0x00d3fb30)我又看不懂。我们要内存中的值(比如上面a的值3)不就行了吗?
其实不然,指针在函数参数传递中大有妙用。请往下看
指针在函数”传值”中的应用
我们知道函数传参过程中,实参和形参结合,也就是形参会等于实参的值,然后函数老大就一脚把实参踹开,之后就不干实参啥事了。
之后在函数内部,函数老大就抓着形参不放,所有的操作都是对实参起作用,和形参无关(暂时这么理解)。下面举个例子
1 |
|
通过这个例子,我们要记住,函数形参和实参结合时,函数内部先将实参的值赋给形参,然后再对形参进行操作。
当形参为地址时,对形参操作也可能会影响实参,下面举例说明
1 |
|
运行结果
通过这个地址我们需要明白两点
当函数形参为指针类型时,表示该函数传递一个指针给形参,然后对形参进行操作。此时形参是一个指针,也就是一个地址,我们通过地址可以使实参发生变化。比如例子中改变*a使得实参b发生变化。示意图如下:
为了和传值区分,我们称上面函数传参方式为传址。其实传址本质上还是传值。
传址妙用
传址可以大大减少内存的消耗,试想一下如果b中存放的是一个占很大内存的对象,如果采用传值方式传递,形实结合会新开辟一块和b一样的空间,供函数内部操作。这样会很消耗内存空间。
但如果我们只传递b的一个地址(一串数字的大小),形实结合时,仅仅需要一小块空间就能够存放下b的地址。然后在函数内仅仅需要通过*就可以操作该地址内部的值。此举大大节约空间。但此举操作可能会影响函数外部的对象的值,使用时应该考虑清楚。
用*对指针指向的值修改
毫无疑问,在函数内部用*对形参指向的值进行修改,函数外部的实参值也会变化。如下
1 |
|
但是如果直接对形参修改(不用*),不会对函数外部的实参值有任何影响。如下
直接对指针本身修改
1 |
|
要正确理解 * 表示对该指针指向的内存单元的值进行操作。
直接对形参修改(不用*),表示对该地址修改了。原来形参还和实参指向同一块地址,形参地址一旦修改,形参就彻底和实参失去联系了。再对形参任何操作均不会对函数外部的实参值有任何影响。这点要注意,容易出错。
常量指针
所谓常量指针就是指向常量的指针,表示为const int*
。不能用*去修改内存中的常量。举例
1 |
|
指针常量
指针常量,表示该地址是一个常量,不能修改。表示为int * const
.举例
1 |
|
C++中的引用,本质上就是指针常量。
C++引用
C++引用是C++中特有的,本质上就是指针常量,如果进行修改,一定是指向的内存变化,而不是指针本身。用&表示。在引用的基础上改变,原值也要变,可以看做一个变量的别名。举例
1 |
|