c++学习 :函数形参4种传递形式:(int a)(int &a)(int *a)(int *& a)

1.void func(int para)

定义一个函数,这个函数想改变a的值(只是个想法)。

void func(int para){
para =4;
cout<<"para地址:"<<&para<<endl;
}

我们再使用它:

int  a =5;
cout<<"a地址:"<<&a<<endl;
func(a);
cout<<a;

输出:

a地址:0x1234
para地址:0x9999//para地址和a不同,这是新分配的内存
5

这时会发现,输出的是5,而不是4。原因是实参a传入函数时,编译器会分配内存空间,函数便会创建一个形式参数para,函数体内部改变的是para这个形参,退出函数时,实参a是不变的。
这里打印了a和para的地址,会发现他们是不同的。
这种形式不可改变实参的值。
在这里插入图片描述

2.void func(int & para)

&这个符号平时表示取地址和引用。
///
int a = 4;
int *q = &a;//表示取地址,赋予q指针
int &x = a;//表示引用,给a取个别名,打印a和x的地址和值,都是一样的
///
在函数形参中出现,表示编译器不给分配内存,para就是实参的别名,如上面第2种用法,就是直接把实参传递过去(int a 会间接传递,因为给形参分配了内存)。

定义一个函数,这个函数想改变a的值(真的想改变):

void func(int &para){
para =4;
cout<<"para地址:"<<&para<<endl;
}

我们再使用它:

int  a =5;
cout<<"a地址:"<<&a<<endl;
func(a);
cout<<a;

输出:

a地址:0x1234
para地址:0x1234//para地址和a相同,这是别名

会发现a被改变了。a = 4。并且打印出来的地址显示,函数体内部para和a的地址一致。
这个函数实现了原本的功能。
这种形式可以改变实参的值。
在这里插入图片描述

3.void func(int* pointer)

int* 大家不陌生,表示函数需要一个指针作为实参。
最好是把int*看做一个整体,和第一种情况做对比。因为int* pointer的形参形式,也会分配内存,创建一个新的指针,其实质和第一种形式是一样的。
定义一个函数,这个函数想改变传入指针指向的值,同时也想改变传入指针保存的地址:

void func(int* pointer){
*pointer=4;
cout<<"函数开始"<<endl;
cout<<"pointer自己的地址:"<<&pointer<<endl;
cout<<"pointer保存的地址:"<<pointer<<endl;
cout<<"pointer指向:"<<*pointer<<endl;
int xxx =520;
pointer = &xxx;
cout<<"xxx值:"<<x<<endl;
cout<<"xxx地址:"<<&xxx<<endl;
cout<<"pointer自己的地址:"<<&pointer<<endl;
cout<<"pointer保存的地址:"<<pointer<<endl;
cout<<"pointer指向:"<<*pointer<<endl;
cout<<"函数结束"<<endl;
}

我们再使用它:

int  a =5;
int* p =&a;
cout<<"a地址:"<<&a<<endl;
cout<<"p自己的地址:"<<&p<<endl;
cout<<"p保存的地址:"<<p<<endl;
func(p);
cout<<"p保存的地址:"<<p<<endl;
cout<<"a值:"<<a<<endl;

输出:

a地址:0x1234
p自己的地址:0x7777//p自己的地址
p保存的地址:0x1234//p指向a
函数开始
pointer自己的地址:0x9999//形参,新分配的指针
pointer保存的地址:0x1234//pointer指向a
pointer指向:5
xxx值:520//xxx值
xxx地址:0x8888//xxx地址
pointer自己的地址:0x9999
pointer保存的地址:0x8888//pointer指向xxx
pointer指向:520
函数结束
p保存的地址:0x1234//p仍然指向a,改变失败
a值:4

这里可以看到,pointer和p保存的都是a的地址。所以函数对*para操作成功改变了a的值。
同时可以发现,ppointerra自己的地址和p自己的地址不一致,说明和第一种情况一样,编译器给pointer分配了自己的内存。
同时,我在函数体内部改变了pointer指向的地址,但是p指向的地址是未改变的。
在这里插入图片描述

补充:在1情况中,实参是不可改变的。比如变量a没有被改变。在本条中,变量a是通过指针改变的。
这里做一下比较:
1和3中,函数都分配了内存空间给形参,因此传入实参都是不可变的。有些人可能会模糊,认为3中变量a的值不是改变了吗?
实际上,1中的实参是变量a,本条实参是指针p,本条中,p也是不可变的,我们也只是通过p的地址(传递给para了,我们再使用para的地址),改变了变量a。

4.void func(int * & pointer)

讲了这么多,其实是为了深刻记忆这一条。
如果在函数内部,既想改变实参指针指向的内容的值,也想改变实参指针自己的地址值。就应该在3条的pointer前加一个&。

我们来比较着看:
int para不可以改变实参,int & para可以改变实参。
int * pointer可以改变指针指向的内容,但是不可改变实参指针。所以只要在pointer前加一个&即可改变传入的指针实参。

定义一个函数:

void func(int* &pointer){
cout<<"函数开始"<<endl;
cout<<"pointer自己的地址:"<<pointer<<endl;
cout<<"pointer保存的地址:"<<pointer<<endl;
int xxx = 520;
pointer = &xxx;
cout<<"xxx地址"<<&xxx<<endl;
cout<<"pointer保存的地址:"<<pointer<<endl;
cout<<"函数结束"<<endl;
}

我们再使用它:

int  a =5;
int* p =&a;
cout<<"a地址:"<<&a<<endl;
cout<<"p自己的地址:"<<&p<<endl;
cout<<"p保存的地址:"<<p<<endl;
func(p);
cout<<"p保存的地址:"<<p<<endl;
cout<<"*p"<<*p<<endl;

输出:

a地址:0x1234
p自己的地址:0x7777
p保存的地址:0x1234//指向a
函数开始
pointer自己的地址:0x7777//和p一样,说明未分配内存,是p的一个别名而已
pointer保存的地址:0x1234//指向a
xxx地址:0x8888
pointer保存的地址:0x8888//改变了pointer的内容
函数结束
p保存的地址:0x8888//保存的是xxx的地址
*p:64267235425//试图打印,发现是奇怪的未初始化的数字

由上面可知,int* &pointer的形参形式,可以改变传入的指针变量内容。p保存的地址指向了xxx,然而因为func函数结束,xxx的生命周期结束,因此再次打印xxx地址发现是一个很奇怪的数字。
在这里插入图片描述

权为学习而写,不足之处敬请指出。

  • 76
    点赞
  • 220
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值