前提

一级指针和引用

已经清晰一级指针和引用。

可参考:指针和引用与及指针常量和常量指针 或查阅其他资料。

一级指针和二级指针

个人觉得文字描述比较难读懂,直接看代码运行结果分析好些,如果想看文字分析,可参考文末参考文章。

例子

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a=5;
  6. int *q=&a;
  7. int **pp=&q;
  8. //下面的两行输出在垂直方向上的相应值相同,由输出可知一级指针和二级指针的关系。
  9. cout<<pp<<" "<<*pp<<" "<<*&pp<<" "<<**pp<<endl;
  10. cout<<&q<<" "<< q <<" "<< &q <<" "<< *q <<endl;
  11. return 0;
  12. }

运行结果:

二级指针传参

  1. #include <iostream>
  2. using namespace std;
  3. void make(int **pp)
  4. {
  5. **pp = 66;//这样只是改变了指向的值,即a, 指向没有改变
  6. }
  7. int main()
  8. {
  9. int a=5;
  10. int *q=&a;
  11. int **pp=&q;
  12. cout<<"address:"<<&pp<<" "<<pp<<" "<<&q<<" "<<q<<" value:"<<*q<<" "<<a<<endl;
  13. make(pp);
  14. cout<<"address:"<<&pp<<" "<<pp<<" "<<&q<<" "<<q<<" value:"<<*q<<" "<<a<<endl;
  15. return 0;
  16. }

运行结果:

如果改为:

  1. #include <iostream>
  2. using namespace std;
  3. void make(int **pp)
  4. {
  5. int * p=new int(66);
  6. *pp=p; //这样便使用函数通过二级指针传参更改了一级指针的指向(值便也改了),但原指向的值不变。其实这和使用一级指针传参改变其指向的值类似,只不过多加了一级指针。
  7. }
  8. int main()
  9. {
  10. int a=5;
  11. int *q=&a;
  12. int **pp=&q;
  13. cout<<"address:"<<&pp<<" "<<pp<<" "<<&q<<" "<<q<<" value:"<<*q<<" "<<a<<endl;
  14. make(pp);
  15. cout<<"address:"<<&pp<<" "<<pp<<" "<<&q<<" "<<q<<" value:"<<*q<<" "<<a<<endl;
  16. }

运行结果:


指针引用传参

例子

  1. #include<iostream>
  2. using namespace std;
  3. void make(int *pp)
  4. {
  5. pp=new int(66); //试图改变p指向的地址,但没有用,看运行结果。
  6. }
  7. int main()
  8. {
  9. int a=5;
  10. int *p=&a; //指针变量指向一个int类型的地址
  11. cout<<"address:"<<&a<<" value:"<<a<<endl;
  12. cout<<"address:"<<p<<" value:"<<*p<<endl;
  13. make(p);
  14. cout<<"address:"<<p<<" value:"<<*p<<endl;
  15. }

运行结果:

这里pp只是p的一个拷贝,pp在函数中相当于一个局部变量。

指针传递参数本质上是值传递的方式,它所传递的是一个地址值。

值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

源自:C++中引用,指针,指针的引用,指针的指针

更改为:

  1. #include<iostream>
  2. using namespace std;
  3. void make(int *&pp)
  4. {
  5. pp=new int(66); //此时pp相当于p的别名,所以改的就是指针p本身,所以更改成功。
  6. }
  7. int main()
  8. {
  9. int a=5;
  10. int *p=&a; //指针变量指向一个int类型的地址
  11. cout<<"address:"<<&a<<" value:"<<a<<endl;
  12. cout<<"address:"<<p<<" value:"<<*p<<endl;
  13. make(p);
  14. cout<<"address:"<<p<<" value:"<<*p<<endl;
  15. }

运行结果:

其实这里pp也是主调函数中p一个拷贝,但不同的是:任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量,所以最终是对于实参的操作。

再多说一点

引用传参与指针传参的不同还在于:指针传递参数时,指针中存放的也是实参的地址,但是在被调函数内部指针存放的内容可以被改变,即可能改变指向的实参,所以并不安全,而引用则不同,它引用的对象的地址一旦赋予,则不能改变。这也正是引用的初衷。

参考:

C++二级指针和指针引用传参的更多相关文章

  1. [ 随手记6 ] C/C++ 形参、实参、按值传参、指针传参、引用传参

    个人原创: 1. 形参:形式上的参数,一般多在函数声明.函数定义的参数上: 2. 实参:实体参数,有实际的值,在运算上被循环使用的值: 3. 按值传参:按值,就是把实际的值传给函数内部: 4. 指针传 ...

  2. Go 到底有没有引用传参(对比 C++ )

    Go 到底有没有引用传参(对比 C++ ) C++ 中三种参数传递方式 值传递: 最常见的一种传参方式,函数的形参是实参的拷贝,函数中改变形参不会影响到函数外部的形参.一般是函数内部修改参数而又不希望 ...

  3. Java中的new关键字和引用传参

    先看看Java中如何使用new关键字创建一个对象的. [java] view plain copy public class Student { public String name; public  ...

  4. Python中的引用传参

    Python中函数参数是引用传递(注意不是值传递).对于不可变类型,因变量不能修改,所以运算不会影响到变量自身:而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量. 引用传参一: >& ...

  5. &符号 (弃用引用传参了,不要用!!)

    写法一 $age = function grow($age) { $age += ; return $age; } echo grow($age) echo $age 写法二 $age = funct ...

  6. c指针与数组,传参问题,指针数组与数组指针的区别,二维数组动态内存分配

    一 数组的结构:顺序存储,看谭浩强中的图,牢记 1.数组名指代一种数据结构:数组 现在可以解释为什么第1个程序第6行的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的 ...

  7. C#调用C++ dll时,结构体引用传参的方法

    写了一个C++的LogLog Logit 四参数等算法的接口dll,给C#调用,但是发现传参有问题 如 extern "C" _declspec(dllexport)  bool ...

  8. c++拷贝构造函数引用传参

    看一道C++面试题: 给出下述代码,分析编译运行的结果,并提供3个选项: A.编译错误  B.编译成功,运行时程序崩溃  C.编译运行正常,输出10 class A { private: int va ...

  9. C# 值传参和引用传参

    值传递:对于个人理解,值传递就像是python中的深拷贝,值传递的内容和原来的内容是两份不同的东西,相互不影响. 引用传递:对于个人理解,引用传递就是python中的复杂多维list的浅拷贝,它传递的 ...

随机推荐

  1. ubuntu18安装pytorch1.3

    环境: ubuntu18 anaconda 创建一个新的环境 conda create -n env_name python=version 激活并进入环境中 conda activate env_n ...

  2. 蓝桥杯 sine之舞(递归)

    Description 最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功.所以他准备和奶牛们做一个“Sine之舞”的游戏,寓教于乐,提高奶牛们的计算能力.不妨 ...

  3. 03.pipeline实现项目自动编译docker镜像自动打包

    https://jenkins.io/zh/doc/book/pipeline/ 官方教程,可以中文.Jenkinsfile就是把pipeline内容保存到文件,然后提交到svn等版本控制库中.安装b ...

  4. Ansible部署rsync、nfs及sersync

    rsync nfs sersync httpd环境: 角色 外网IP(NAT) 内网IP(LAN) 主机名 Rsync服务端 eth0:10.0.1.51 eth1:172.16.1.51 backu ...

  5. [USACO09OCT]谷仓里的回声Barn Echoes(hush、STL)

    https://www.luogu.org/problem/P2957 题目描述 The cows enjoy mooing at the barn because their moos echo b ...

  6. QLIKVIEW-日期格式,数字格式写法

    LOAD T_SAL_ORDER.LE_ID, [T_SAL_ORDER.LCY CODE], T_SAL_ORDER.SYSTEM, T_SAL_ORDER.#DataDateTime, T_SAL ...

  7. CHINA SHOP 2019 | 奇点云“云+端”产品及解决方案赋能线下零售

    第二十一届中国零售业博览会(CHINA SHOP) 在山东青岛世界博览城盛大开幕 作为CHINA SHOP的老朋友 奇点云自然不会缺席 China Shop逛展直击灵魂“双拷问”: No.1 今年CH ...

  8. 吴裕雄--天生自然python机器学习:KNN-近邻算法在手写识别系统上的应用

    需要识别的数字已经使用图形处理软件,处理成具有相同的色 彩和大小® : 宽髙是32像 素 *32像素的黑白图像.尽管采用文本格式存储图像不能有效地利用内 存空间,但是为了方便理解,我们还是将图像转换为 ...

  9. 系统学习javaweb4----CSS层叠样式表(结束)

    摘要:这几天临近过年,事情有点多,学习总是段段续续的,今天总算完成了CSS的基本知识学习. 学习笔记: 西瓜学习javaweb 1.css简述. 1.1 css是什么?有什么作用? HTML----- ...

  10. [LC] 149. Max Points on a Line

    Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...