根据下列代码回答下列问题。
// Created by 黑马程序员.
#include "iostream"
using namespace std;
/*
* 引用传参:
* void func(int &a, int &b);
*/
void switch_num1(int a, int b) // 值传递
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
void switch_num2(int * a, int * b) // 地址传递
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void switch_num3(int &a, int &b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
int main()
{
int x1 = 1;
int y1 = 2;
switch_num1(x1, y1);
cout << "x1=" << x1 << endl;
cout << "y1=" << y1 << endl;
int x2 = 10;
int y2 = 20;
switch_num2(&x2, &y2);
cout << "x2=" << x2 << endl;
cout << "y2=" << y2 << endl;
int x3 = 100;
int y3 = 200;
switch_num3(x3, y3);
cout << "x3=" << x3 << endl;
cout << "y3=" << y3 << endl;
return 0;
}
D:\CLion_code\cmake-build-debug\CLion_code.exe
x1=1
y1=2
x2=20
y2=10
x3=200
y3=100
Process finished with exit code 0
函数传参有哪3种方式呢?第一种、值传递,会复制值,无法对实参本身产生影响。第二种、地址传递,会复制地址,对实参本身可以产生影响,但指针写法麻烦。第三种、引用传递,像普通变量那样操作,但对实参本身可以产生影响。值传递、地址传递、引用传递三者在形参定义、传递内容、是否对实参有影响、是否直接对内存操作这4点有什么不同呢。第一点、在形参定义上,值传递形参定义是普通变量 int a,地址传递形参定义是指针变量int *a,引用传递的形参定义是引用int &a。第二点、在传递内容上、值传递是复制变量值,完成数据传递,而地址传递是复制指针值,完成地址传递,而引用传递是复制引用对象。第三点、在对实参的影响上、值传递不对实参产生影响,地址传递对实参产生影响,引用传递对实参产生影响。第四点、在对内存操作上,值传递不对内存直接操作,地址传递会对内存进行直接操作,引用传递不会对内存直接操作。
问题解答:
在C++中,函数传参有三种方式:值传递、地址传递和引用传递。下面我们逐一分析这三种方式,并比较它们在形参定义、传递内容、对实参的影响以及是否对内存进行直接操作等方面的区别。
1. 值传递
值传递是将实参的值复制一份传递给形参,在函数内部操作的是形参的副本,因此不会对实参产生影响。
- 形参定义:普通变量,例如
int a
。 - 传递内容:传递的是变量的值,即对变量进行复制。
- 是否影响实参:不会对实参产生影响,因为操作的是实参的副本。
- 是否直接对内存操作:不会直接操作内存,只是值的拷贝。
示例:
void switch_num1(int a, int b) // 值传递
{
int tmp = a;
a = b;
b = tmp;
}
在 main
函数中调用 switch_num1(x1, y1)
,因为是值传递,x1
和 y1
的值不会被改变:
int x1 = 1;
int y1 = 2;
switch_num1(x1, y1); // 调用值传递函数
cout << "x1=" << x1 << endl; // 输出 x1=1
cout << "y1=" << y1 << endl; // 输出 y1=2
2. 地址传递(指针传递)
地址传递是通过传递变量的地址(指针),函数可以通过指针直接操作实参的内存地址,从而对实参产生影响。
- 形参定义:指针变量,例如
int* a
。 - 传递内容:传递的是变量的地址(指针)。
- 是否影响实参:会对实参产生影响,因为操作的是指向实参的内存地址。
- 是否直接对内存操作:会对内存直接操作,因为函数内部通过指针操作内存。
示例:
void switch_num2(int* a, int* b) // 地址传递
{
int tmp = *a;
*a = *b;
*b = tmp;
}
在 main
函数中调用 switch_num2(&x2, &y2)
,由于传递的是地址,x2
和 y2
的值被交换:
int x2 = 10;
int y2 = 20;
switch_num2(&x2, &y2); // 调用地址传递函数
cout << "x2=" << x2 << endl; // 输出 x2=20
cout << "y2=" << y2 << endl; // 输出 y2=10
3. 引用传递
引用传递是通过传递实参的引用,函数内部的形参实际上是实参的别名,任何对形参的操作都会直接作用于实参。
- 形参定义:引用变量,例如
int& a
。 - 传递内容:传递的是变量的引用,即别名。
- 是否影响实参:会对实参产生影响,因为操作的是实参的别名。
- 是否直接对内存操作:不会直接操作内存,但因为引用与实参共享内存空间,所以操作引用相当于操作实参。
示例:
void switch_num3(int& a, int& b) // 引用传递
{
int tmp = a;
a = b;
b = tmp;
}
在 main
函数中调用 switch_num3(x3, y3)
,由于传递的是引用,x3
和 y3
的值被交换:
int x3 = 100;
int y3 = 200;
switch_num3(x3, y3); // 调用引用传递函数
cout << "x3=" << x3 << endl; // 输出 x3=200
cout << "y3=" << y3 << endl; // 输出 y3=100
三者的比较
比较点 | 值传递 | 地址传递(指针传递) | 引用传递 |
---|---|---|---|
形参定义 | int a | int* a | int& a |
传递内容 | 复制变量的值 | 复制变量的地址(指针) | 传递变量的引用(别名) |
是否影响实参 | 否 | 是 | 是 |
是否直接操作内存 | 否 | 是 | 否,但对实参有直接影响 |
总结
- 值传递:传递的是实参的值,函数内部操作的是该值的副本,不会对实参产生影响。
- 地址传递:传递的是实参的地址,通过指针直接修改实参的值,会对实参产生影响。
- 引用传递:传递的是实参的引用,函数操作的就是实参本身,会对实参产生影响,且操作方式更加直观。