写在最前面:本篇博客的主要内容参考了一位大佬的博客:C/C++中的值传递,引用传递,指针传递,指针引用传递,在这里贴出来以示尊敬!
在C++中,对子函数的调用过程中,常常有一下几种方式来传递参数:值传递、指针传递、引用传递以及指针引用传递。现将以上几种传递方式的原理及示例总结如下:
1、值传递
值传递的实质是:被调函数在执行过程中,对传递进来的实参值进行复制(在栈上开辟了新的内存空间)形成了局部变量
,来执行后续的操作。
示例如下:
void f( int p){
printf("\n%x",&p);
printf("\n%x",p);
p=0xff;
}
void main()
{
int a=0x10;
printf("\n%x",&a);
printf("\n%x\n",a);
f(a);
printf("\n%x\n",a);
}
输出结果如下:
通过上例我们可以看到,int a=0x10,存放的地址为0x12ff4、,值为10,当调用f(a)时,传递给p的值为10(此处的传递是通过内容的复制
),但是p的地址为0x12fef4(是保存复制结果(实参内容)的内存的地址
),当改变p=0xff时,是改变地址为0x12fef4中的内容,并没有改变0x12ff44中的内容,所以调用f(a)后a的值仍然为0x10,所以值传递无法改变变量的值。示意图如下:
原理如下:
2、引用传递
引用传递的实质是:引用为实参对象的别名,在进行参数传递时,用的是实参对象
,当在被调的子函数中对形参进行改变时,实际修改的就是对传递进来的实参对象进行修改。
示例如下:
void f( int & p){
printf("\n%x",&p);
printf("\n%x",p);
p=0xff;
}
void main()
{
int a=0x10;
printf("\n%x",&a);
printf("\n%x\n",a);
f(a);
printf("\n%x\n",a);
}
整个运算过程的原理如下:
3、指针传递
指针参数
传递本质上是值传递
(传值方式
),它所传递的是一个地址值
。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从而形成了实参的一个副本(替身)
。值传递的特点是,被调函数对形式参数的任何操作都是作为局部变量
进行的,不会影响主调函数的实参变量的值(注意!这里说的值是指实参指针自身的地址不变,但是该指针指向的内容有可能会发生改变(解引用操作时对形参指针的操作会引起实参指针所指向的内容发生改变
))。
示例如下:
void f( int*p){
printf("\n%x",&p);//保存变量p的内容的内存单元的地址
printf("\n%x",p);//变量p的内容
printf("\n%x\n",*p);//变量p的内容(一个地址)所指向的内存单元的内容
*p=0xff;//解引用操作。
}
void main()
{
int a=0x10;
printf("\n%x",&a);
printf("\n%x\n",a);
f(&a);
printf("\n%x\n",a);
}
运行结果如下:
整个运算过程的原理如下:
上述图片表述有点问题(上图来自开头链接的博客中,这里懒得画了),具体说明下:p的内容是a的地址:ox12ff44,*p就是对地址为ox12ff44的内存单元的内容进行改变。而对p的改变,是对p的内容(即对地址为ox12fef4的内存单元的内容)进行改变,并没有对地址为ox12ff44的内存单元的内容有任何影响
。
4、指针的引用传递
在实际的应用当中,常常还会用到一种对指针的引用传递。其本质上属于应用传递。
示例如下:
void f( int*&p){
printf("\n%x",&p);//引用p的地址,与实参变量的地址一致。
printf("\n%x",p);//p的内容,实参的值(一个指向整形变量的地址值)
printf("\n%x\n",*p);//p的内容所指向的内存单元的值。
*p=0xff;//解引用操作,修改p的内容所指向的内存单元的值。
}
void main()
{
int a=0x10;
printf("\n%x",&a);//保存a变量值的内存单元的地址
printf("\n%x\n",a);//变量a的值
int *b=&a;//将保存变量a的值的内存单元的地址赋给指针b(b的内容就是a的地址).
printf("\n%x",&b);//b内存单元的地址。该地址保存的是a的地址。
printf("\n%x",b);//a的地址。
printf("\n%x\n",*b);//变量a的值。
f(b);
printf("\n%x\n",a);
}
运行结果如下:
原理如下:
为了使用指针的引用传递我们要新建一个指针b,然后将b的引用传递给p,其实p就是b的一个拷贝,*p=b都指向a,所以改变p的内容也就改变a的内容。示意图如下:
进一步举例如下:
void f( int*p){
printf("\n%x",&p);
printf("\n%x",p);
printf("\n%x\n",*p);
*p=0xff;
}
void main()
{
int a=0x10;
printf("\n%x",&a);
printf("\n%x\n",a);
int *b=&a;
printf("\n%x",&b);
printf("\n%x",b);
printf("\n%x\n",*b);
f(b);
printf("\n%x\n",a);
printf("\n%x\n",b);
}
运行结果如下:
原理如下所示: