C++中的二级指针和指针引用函数传参
在函数的使用过程中,我们都明白传值和传引用会使实参的值发生改变。那么能够通过传指针改变指针所指向的地址吗?
在解决这个问题之前,也许我们应该先了解指针非常容易混淆的三个属性:
①.指针变量地址(&p)
②.指针变量指向的地址(p,存储数据的地址)
③.指针变量指向的地址的值(*p)
当我们将指针变量与其它变量比较之后就会发现,指针变量同其它变量是相似的,只是多了最后一种操作。比如一个int类型的变量,int x=5;&x取出存储5这个数据的地址,同样,&p也是存储指针的地址,p就是这个地址里面保存的值,也就是指向的地址。只是与其它变量不同的是,它除了这两种操作之外,还有一个解引用操作符(*p)去获取指针变量指向的地址里面保存的值。
一.指针引用
void make(int *pp)
{
pp=new int(); //试图改变p指向的地址
}
int main()
{
int a=;
int *p=&a; //指针变量指向一个int类型的地址
cout<<"address:"<<&a<<" value:"<<a<<endl;
cout<<"address:"<<p<<" value:"<<*p<<endl;
make(p);
cout<<"address:"<<p<<" value:"<<*p<<endl;
}
运行结果如下:我们这里虽然使用的是传指针,但是却不是直接改变指针变量指向的地址的值,却是想通过改变指针变量指向的地址来修改它的值,显然这样失败了。
如果我们希望在函数里面修改指针变量存储的地址而不是它的值,这个时候就需要指针引用了。类似于普通变量传入变量引用,我们也传入一个指针引用,在函数里面,你可以将pp认为和p都是这个指针变量(&p==&pp),不似传入指针参数的时候形参和实参的变量(&p!=&pp)地址不一样。此时我们操作pp的值就是更改了p的值。
void make(int *&pp)
{
pp=new int(); //改变p指向的地址
}
运行结果如下:当我们修改传入参数为指针的引用的时候就可以修改指针变量所指向的地址了,可以看见,传入指针引用可以修改指针变量的值(p)和指向的值(*p)。
二.二级指针
指向指针的指针变量称为二级指针。
如果pp是一个二级指针,那么有如下属性:
①.二级指针的地址(&pp)
②.二级指针的地址保存的地址(pp)
③.二级指针的地址保存的地址,该地址里面保存的地址(*pp)
④.二级指针的地址保存的地址,该地址里面保存的地址里面的数据(**pp)
除了上面传入指针引用改变一级指针指向的地址以外,我们还可以通过传入一个二级指针去修改它对应的一级指针指向的地址,同样达到了修改指针变量的效果。二级指针的指向的地址存储的值就是一级指针指向的地址。对一级指针变量解引用得到的是指针指向的地址存储的数据,二级指针变量解引用得到的也是该二级指针指向的地址存储的地址值。
void make(int **pp)
{
int * p=new int();
*pp=p; //二级指针的解引用被赋值需要得到一个一级指针变量,上图中二级指针的示意图中 *pp=p
}
int main()
{
int a=;
int *q=&a;
int **pp=&q;
cout<<"address:"<<&pp<<" "<<pp<<" "<<&q<<" "<<q<<" value:" <<*q<<endl;
make(pp);
cout<<"address:"<<&pp<<" "<<pp<<" "<<&q<<" "<<q<<" value:"<<*q<<endl;
}
运行结果如下:通过对二级指针的解引用赋值成功修改了一级指针指向的地址。如果仅仅在make函数里面对**pp=66;操作,那么所有的地址不会改变,仅仅会改变值为66。
C++中的二级指针和指针引用函数传参的更多相关文章
- 简单计算器的C实现-函数指针,main函数传参
/** 程序功能:简单计算器,实现加减乘除平方* 作者版本日期:2015.11.08 zhouhb OK* 源代码:李明 <新概念C语言培训>第33集 C语言Shell命令解释器的实现* ...
- shell中的特殊变量和函数传参
shell中的特殊变量 $? :上一个命令的执行状态返回值 $#::参数的个数 $*:参数列表,所有的变量作为一个字符串 $@:参数列表,每个变量作为单个字符串 $1-9,${10}:位置参数 $$: ...
- JS中的函数传参
前言: 函数分为有参有返回值,有参无返回值,无参无返回值,无参有返回值:那么对于无参数的函数你想使用函数的调用怎么办呢?如果你想封装一个代码,实现多种功能,但是形参大于实参或者实参大于形参又该如何?本 ...
- 看似无参却有参-----JS中的函数传参
事件event JS的事件event是一个非常大的对象,不管是什么事件,事件的详情都会绑定到全局变量event中.这样做之所以安全,就是因为JS是单线程的. <html> <body ...
- VC/MFC中通过CWebPage类调用javascript函数(给js函数传参,并取得返回值)
转自:http://www.cnblogs.com/javaexam2/archive/2012/07/14/2632959.html ①需要一个别人写好的类CWebPage,将其对于的两个文件Web ...
- C语言中的二级指针(双指针)
原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/7220688 C语言更多查看 C语言使用注意事项(一) C语言使用注意事项(二) ...
- C++二级指针和指针引用传参
前提 一级指针和引用 已经清晰一级指针和引用. 可参考:指针和引用与及指针常量和常量指针 或查阅其他资料. 一级指针和二级指针 个人觉得文字描述比较难读懂,直接看代码运行结果分析好些,如果想看文字分析 ...
- C++中值传递、指针传递、引用传递的总结
C++中值传递.指针传递.引用传递的总结 指针传递和引用传递一般适用于:函数内部修改参数并且希望改动影响调用者.对比值传递,指针/引用传递可以将改变由形参"传给"实参(实际上就 ...
- c++中函数参数传递(值传递、指针传递,引用传递)进一步认识
概念 首先从概念上来说一下这几种函数传参方式及区别: 1.值传递:形参是实参的拷贝,改变函数形参的值并不会影响外部实参的值,这是最常用的一种传参方法,也是最简单的一种传参方法,只需要传递参 ...
随机推荐
- 利用userData实现客户端保存表单数据
对于多数网页制作的朋友,实现在客户端保存在网页表单上的信息,比较多的是采用Cookie技术来实现,这些功能例如:下拉列表框选择的选项,文本框输入的数据等.事实上,我们可以利用微软DHTML默认行为中的 ...
- UVA11248_Frequency Hopping
给一个有向网络,求其1,n两点的最大流量是否不小于C,如果小于,是否可以通过修改一条边的容量使得最大流量不小于C? 首先对于给定的网络,我们可以先跑一遍最大流,然后先看流量是否大于C. 然后保存跑完第 ...
- ubuntu在终端使用的常用命令
1.ubuntu系统显示IP地址:ifconfig 2.ubuntu系统文件命令: cat:显示文本文件内容,全部文本.格式:cat filename more:显示文件内容,分页显示,回车逐行下翻. ...
- JVM工作原理 - 内存空间
大多数 JVM 将内存区域划分为 Method Area(Non-Heap)(方法区) ,Heap(堆) , Program Counter Register(程序计数器) , VM Stack( ...
- Gauss Prime UVA - 1415
题意:给出a和b判定是否为高斯素数 解析: 普通的高斯整数i = sqrt(-1) 高斯整数是素数当且仅当: a.b中有一个是零,另一个是形为或其相反数的素数: 或a.b均不为零,而为素数. 这题 提 ...
- 【刷题】BZOJ 2959 长跑
Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动.一时间操场上 ...
- 【spring学习笔记二】Bean
### bean的三种实例化方式: 1.构造 2.静态工厂 3.实例工厂 其中,工厂就是工厂的概念,工厂函数factor-method会返回她生产出来的产品类. 而构造初始化也可以选择初始化方式和销毁 ...
- RRDtool绘制lvs连接数图形
需求:用RRDtool绘制lvs的连接数图形 RRDtool是一个强大的绘图工具,作者是Tobias Oetiker. RRD全称Round Robin Database,轮转数据库,也是一个时间序列 ...
- JMH 使用指南 - java 性能测试
JMH 篇 JMH,即Java Microbenchmark Harness 翻译:java 微基准测试 工具套件.## 1.添加依赖```<dependency> <groupId ...
- 2:spring中的@resource
@Resource 其实是spring里面的注解注入. @Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定, 如果没有指定name属性,当注解写在字段 ...