参数的传递前面讲过有值传递和指针传递,其实引用也是可以进行参数传递的,并且在工作和项目中,引用传参是一种比较常用并且比较好理解的方式。下面我们进入引用传参之路。。。
在上路之前,先回顾一下值传递和指针传递。
值传递:在函数调用时,将实际参数的值复制出来一个作为分身传入到调用的函数中,在调用函数中修改参数的值不会影响到实际参数的值。
指针传递:在函数调用时,将指针变量复制出来一个分身,这个分身和指针变量指向的内存区域是一样的。对指针的分身指向的内存内容进行改变的时候,原指针变量指向的变量内容也跟着改变。
引用传递跟指针函数类似,在调用函数中修改参数的值的时候,也会改变实际参数的值。下面来看一个例子来对这三种传参方式进行比较,帮助大家有一个直观的理解:
#include<iostream>
using namespace std;
void test1(int a) //值传参
{
int x = 10;
a = x - a;
}
void test2(int &a) //引用传参
{
int x = 10;
a = x - a;
}
void test3(int *a) //指针传参
{
int x = 10;
*a = x - *a;
}
void main()
{
int i = 1;
int* p;
p = &i;
cout << "调用test1值传递的方式得到的结果" << endl;
test1(i);
cout << "调用之后i的值是: " << i << endl;
cout << "调用之后i的地址是: " << &i << endl;
cout << "调用test2值传递的方式得到的结果" << endl;
test2(i);
cout << "调用之后i的值是: " << i << endl;
cout << "调用之后i的地址是: " << &i << endl;
cout << "调用test3值传递的方式得到的结果" << endl;
test3(p);
cout << "调用之后i的值是: " << i << endl;
cout << "调用之后i的地址是: " << &i << endl;
}
三种传参方式,首先来看第一种,这个是比较好理解的,将i的值传递到test1中运行之后,i的值仍为1,然后再将i传递到test2中,test2是通过引用传参的方式,将i传递进去之后,i通过运算再赋值到i上,得到的i值改变为9,并且由于是引用传递,实际参数i的值也改变为9,再通过test3函数传递,这是指针传递的方式,同样也会改变实参i的值,因此i又变为了1。i的地址再整个运行的过程中不发生改变,运行结果如图:
通过这种方式,相信大家对各个传参方式有了进一步的理解。
除此之外,还有右值引用传递参数。所谓右值引用传参就是使用字面值、表达式或者是函数返回值等临时变量作为函数参数进行传递。对临时变量采用值传参的时候,会产生一个和参数一样大小的分身;采用左值引用传参时,会被编译器阻止。举个例子:
#include <iostream>
using namespace std;
static int i = 10; //静态全局变量
void test(int&& a)
{
i += a;
}
int getint()
{
int a = 10;
return a;
}
void test(int& a) //左值引用,重载函数
{
i -= a;
}
int main()
{
int j = 8;
cout << "i=" << i << endl;
test(6);
cout << "i=" << i << endl;
test(getint() + 3);
cout << "i=" << i << endl;
test(j);
cout << "i=" << i << endl;
return 0;
}
i 是静态全局变量,每次调用 i 的值的时候,i 的值都不会被释放;
第一次使用test的时候,参数是一个字面值,是临时变量,因此调用的是右值引用传参方式的test,得到结果 i=16;
然后是第二个test(),参数为临时变量,因此仍为右值引用传参方式的test,得到的 i=29;
第三个test是左值引用传参的test,此时的 i=29,运算之后得到的结果是21。运行结果如图
希望鄙人的薄见可以对大家带来帮助,学习更进一步!