您的位置:首页 > 编程语言 > C语言/C++

C++之值传递、指针传递和引用传递---补充(4)《Effective C++》

2017-07-22 11:44 253 查看
在上篇博客中突然发现自己对C++中的值传递的应用场景以及内存分配状况不清楚,所以进行一个紧急补充。

1)值传递(pass-by-value):

值传递,传递的是内存的副本,形参是实参的拷贝,改变形参的值不会影响实参,最简单的一种传递方式,被调函数的形参作为被调函数的局部变量处理,即在堆栈中开辟内存空间(即为形参开辟空间)以存放主调函数传过来的实参值,对实参值进行了一个拷贝而已!当被调函数执行结束后,局部变量形参被释放,可以通过return函数返回到主函数中,进而存放在主函数的寄存器中!不会意向实参的值!

2)指针传递(pass-by-pointer):

在理解指针传递的时候,请参看如下代码:

#include <iostream>
#include <string>
using namespace std;
void changePtr(int a[],int n,int *p11,int *p21){
if (a != NULL){
p11 = &a[0];
p21 = &a[n - 1];
}
}

int main(){
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int a0 = 10;
int a1 = 15;
int *p1 = &a0;
int *p2 = &a1;
cout << p1 << " " << p2 << endl;
changePtr(a, 10, p1, p2
4000
);
cout << p1 << " " << p2 << endl;
cout << *p1 << endl;
cout << *p2 << endl;
return 0;
}


运行结果如下:



可以发现我们对一个函数,我们原计划打算在函数内改变指针的值,通过指针返回到外部函数中,却不小心发现指针指向的地址并没有改变,这是为什么呢?学习C++,搞清C++的内存分配很重要,下面我们就进行一个深度剖析!函数changePtr中我们传递声明了4个参数,其中两个是指针类型,函数压栈,局部变量p11,p21变量指向p1,p2指针所指向的地址,然后在函数中改变了p11指针和p21指针所指向的地址,然鹅趣却并没有返回吧,等到函数执行结束,局部变量p11,p21被销毁了,没有了吧,p1,p2里面的值有改变吗?没有,p1和p2所指向的位置有改变吗?木有,所以当然输出的结果不会变呀!

因此,指针传递,传递的是地址的副本,不能改变外部传进来指针的指向地址,却可以通过一系列操作改变外部指针指向地址中的内容!

3)引用传递(pass-by-reference):

引用传递,这是我们关注的点,当通过引用传递的时候,传递的是什么呢?从汇编的角度来说,其实也是地址,但和指针传递不同的是指针传递被调函数中可以修改局部变量指针所指向的地址,也可以改变局部变量指针所指向内存地址中的值,引用只保留第二个特性,默认的是通过引用,指针的值为常量指针,不会进行指针所指向地址的修改,只会修改指针所指向的地址中的值的修改,有些拗口,下面我们来看如下代码:

#include <iostream>
#include <string>
using namespace std;
void changePtr2(int a[], int n, int&a1, int &a2){
if (a != NULL){
a1 = a[0];
a2 = a[n-1];
}
}
int main(){
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int a0 = 10;
int a1 = 15;
changePtr2(a, 10, a0, a1);
cout << a0 << " " << a1 << endl;
return 0;
}


运行结果如下:



其实际正如changePtr3函数中所写的那样:

void changePtr3(int a[], int n,  int* const p1, int* const p2){
if (a != NULL){
*p1 = a[0];
*p2 = a[n-1];
}
}


总结:

在理解C++的值传递、引用传递和指针传递三种传递方式的时候,需要深刻理解C++的内存拷贝机制,这样才会对C++的参数传递有一个更清楚和准确的理解,在雷区前行,需要勇者,更需要智者!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: