C++ 中的传值调用和传引用调用

2025 年 8 月 29 日 | 6 分钟阅读

C 语言中将值或数据传递给函数有两种方式:传值调用和传引用调用。传值调用不会修改原始值,而传引用调用会修改原始值。

CPP Call by value and call by reference in cpp 1

在 C++ 编程语言中,主要有两种方法用于将参数传递给函数:传值调用和传引用调用。这些方法解释了数据如何传递给函数以及如何处理数据更改。在传值调用函数中,实际值不会被修改,但在传引用调用中会被修改。在这里,我们将逐一讨论 C++ 编程语言中的传值调用传引用调用

C++ 中的传值调用

传值调用函数中,参数的原始值通常会传递给函数。此方法允许我们将原始参数复制到形式参数中。传值调用函数对这个参数副本进行操作,它不能修改原始数据。

如果我们希望修改函数参数的值,它只对当前函数有效。这意味着参数内部的任何更改都不会影响原始变量。

语法

它具有以下语法:

示例

让我们举一个例子来说明 C++ 中的传值调用

示例

编译并运行

输出

The value of the data is: 8

说明

在这个例子中,数据在 main() 函数中被初始化为值 3。之后,调用 change() 函数并传入 data 作为参数,但是当这个函数通过值传递时,只有副本在 change() 函数内部被修改。最后,它打印数据的值。

C++ 中的传引用调用

在 C++ 中,传引用调用是一种用于将值传递给函数参数的方法。它允许函数直接修改实际变量的值,因为实际参数和形式参数都引用相同的变量。函数内部对参数所做的任何更改都会影响原始参数。

注意:要理解传引用调用,我们必须具备指针的基本知识。

示例

让我们举一个例子来说明 C++ 中的传引用调用。

示例

编译并运行

输出

The value of a is: 80
The value of b is: 200  

说明

在这个例子中,我们使用了 swap() 函数,它接受两个指针 int *x 和 int *y。在 swap() 函数内部,使用临时变量 swap 交换了值。之后,main() 函数中的原始变量被修改,因为函数通过指针直接访问它们的内存位置。

何时在 C++ 中使用传值调用和传引用调用

在 C++ 中,有几种情况会使用传值调用和传引用调用。其中一些如下

传值调用

传值调用可以在以下情况使用

  • 我们不需要修改函数的原始参数。
  • 我们需要创建数据的副本而不是原始数据。
  • 我们不处理递归的回溯。

传引用调用

传引用调用可以在以下情况使用

  • 我们需要在函数内部更改原始变量的值。
  • 我们处理大量数据,因为传引用调用不会创建数据的副本。
  • 我们有一个大型对象,并希望避免复制此对象的开销。

传值调用和传引用调用的优点

在 C++ 中,传值调用和传引用调用有几个优点。这些函数的一些主要优点如下

传值调用的优点

  • 传值调用不会修改原始变量。
  • 无论何时调用此函数,它都不会影响实际参数的原始值。
  • 它适用于那些只需要读取数据的函数,因为它不能修改数据。
  • 没有内存泄漏或悬空指针的风险,因为副本在处理结束时默认销毁。
  • 在此函数中,原始参数的值传递给形式参数。因此,对形式参数所做的任何修改都不会影响原始参数。

传引用调用的优点

  • 传引用调用直接修改原始值。
  • 它对于大型数据结构和需要修改的数据非常有用。
  • 它有助于我们避免意外发生的修改。
  • 它不会创建重复数据来存储值,从而有助于节省内存空间。

传值调用和传引用调用的缺点

在 C++ 中,传值调用和传引用调用有几个缺点。这些函数的一些主要缺点如下

传值调用的缺点

传值调用不适合更新或更改原始变量的值。

  • 在使用大型对象(如数组、字符串、结构体、向量等)时,它需要大量的内存空间。
  • 它不能有效地与动态内存分配一起工作。
  • 如果函数使用传值调用被调用太多次,每次调用都会创建新的副本,导致栈溢出。

传引用调用的缺点

  • 由于函数在传引用调用中处理原始数据,意外的更改可能会修改实际变量,从而导致意外错误。
  • 如果在传引用调用中使用指针,意外传递 nullptr 可能会引发运行时错误。
  • 由于函数通过引用传递,理论上它不再是纯粹的。
  • 当多个引用引用相同的数据时,更改一个引用会影响所有引用。

C++ 中传值调用和传引用调用的区别

传值调用和传引用调用的一些主要区别如下

特点传值调用传引用调用
传递的值值的副本被传递给函数。值的地址被传递给函数。
变化函数内部所做的更改不会反映在其他函数中。函数内部所做的更改也会反映在函数外部。
内存位置实际参数和形式参数将在不同的内存位置创建。实际参数和形式参数将在相同的内存位置创建。
数据类型它适用于基本和简单的数据类型,包括 int、float、char 等。它适用于复杂的数据类型,如数组、结构体、字符串等。
性能它降低了意外副作用的风险。它增加了意外副作用的风险。
 由于数据传输量较小,它比传引用调用更快。由于需要通过引用访问数据,它可能会更慢。

C++ 传值调用和传引用调用 MCQ

1. 使用传值调用调用函数的正确语法是什么?

  1. fun;
  2. fun(*x, *y);
  3. fun(x, y);
  4. fun(&x, &y);
 

答案:(c) fun(x, y);


2. 当函数更改通过引用传递的 C++ 变量时会发生什么?

  1. 原始值将被更改。
  2. 程序显示错误。
  3. 只有本地副本会被修改。
  4. 创建新变量
 

答案:(a) 原始值将被更改。


3. 以下代码的输出是什么?

编译并运行
  1. 22
  2. 15
  3. 7
  4. 编译错误
 

答案:(b) 15


4. 当传递大型对象作为参数时,哪个函数更高效?

  1. 传引用调用
  2. 传值调用
  3. 两者效率相同
  4. 以上都不是
 

答案:(a) 传引用调用


5. 以下关于 C++ 传值调用的选项哪个是正确的?

  1. 实际变量被修改。
  2. 函数直接处理实际内存位置。
  3. 实际变量保持不变。
  4. 以上都不是。
 

答案:(c) 实际变量保持不变。