1. 值传递

我们先来看一段代码

  1. //代码5.1
  2. #include <iostream>
  3. void Exchg1(int , int);
  4. int main()
  5. {
  6. using namespace std;
  7. int a=4,b=6;
  8. Exchg1(a, b);
  9. cout << "a = "
  10. << a
  11. << ","
  12. << "b = "
  13. << b << endl;
  14. //return 0;
  15. }
  16. void Exchg1(int x,int y)
  17. {
  18. using namespace std;
  19. int temp;
  20. temp = x;
  21. x = y;
  22. y = temp;
  23. cout << "x = "
  24. << x
  25. << ","
  26. << "y = "
  27. << y << endl;
  28. }

程序的运行结果如下图
image.png发现调用值交换函数后,a、b并没有像预期的那样调换,而是原封不动地输出了;
这里就涉及到一个知识误区,我们把调用Exchg1函数的过程单独拿出来

//代码5.2
    int x = a;
    int y = b;
    int temp;
    temp = x;
    x = y;
    y = temp;
    cout << "x = "
         << x
         << ","
         << "y = "
         << y << endl;

第2、3行代码是调用函数时的两个隐含动作 ;
总结一下, 函数在调用时是隐含地把实参 a、b 的值分别赋值给了 x、y, 之后在你写的 Exchg1 函数体内再也没有对 a、b 进行任何的操作了。交换的只 是 x、y 变量。并不是 a、b。当然 a、b 的值没有改变,函数只是把 a、b 的 值通过赋值传递给了 x、y,函数里头操作的只是 x、y 的值并不是 a、b 的值。

  1. 地址传递 ```cpp //代码5.2

include

void Exchg2(int px, int py);

int main() { using namespace std; int a = 4,b = 6; Exchg2(&a, &b); cout << “a = “ << a << “,” << “b = “ << b << endl; return 0; }

void Exchg2(int px,int py) { using namespace std; int temp = px; px = py; py = temp; cout << “px = “ << px << “,” << “py = “ << py << endl; }

代码5.2的运行结果如下图所示<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/23214581/1636987928084-db33ee3a-ba7e-4280-ad42-9624da4ea2a0.png#clientId=u8a98acd2-64a2-4&from=paste&id=u3eb686ec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=267&originWidth=789&originalType=binary&ratio=1&size=24693&status=done&style=shadow&taskId=ubdcd7c09-1a0c-4850-a566-79bb7a8f29a)<br />和值传递不同,这次a、b成功地交换了值<br />写出Exchg2函数的过程
```cpp
px = &a; /* ← */ 
py = &b; /* ← 请注意这两行,它是调用 Exchg2 的隐含动作。*/ 
int tmp = *px; 
*px = *py; 
*py = tmp;

指针 px、py 的值已经分别是 a、b 变量的地址值了。接下来,对px、py 的操作当然也就 是对 a、b 变量本身的操作了。所以函数里头的交换就是对 a、b 值的交换了。

3.引用传递

//代码5.3
#include <iostream>

void Exchg3(int &x, int &y); /* 注意定义处的形式参数的格式与值传递不同 */

int main()
{
    using namespace std;
    int a=4,b=6;
    Exchg3(a, b);/*注意:这里调用方式与值传递一样*/ 
    cout << "a = "
         << a
         << ","
         << "b = "
         << b << endl;
    //return 0;
}

void Exchg3(int &x,int &y)
{
    using namespace std;
    int temp;
    temp = x;
    x = y;
    y = temp;
    cout << "x = "
         << x
         << ","
         << "y = "
         << y << endl;
}

程序的运行结果如下图所示,从结果来看是成功的
image.png
注意比较与值传递代码的不同, 参数 x、 y 是 int 的变量,调用时我们可以像值传递 ;
x、y 前都有一个取地址符号“&”。有 了这个,调用 Exchg3 时函数会将 a、b 分别代替了 x、y 了,这就是x、y 分别引用了 a、b 变量。

4.值传递和引用传递的比较

函数参数的三种传递方式 - 图3