学习C ++:值和参考参数

One of the most difficult concepts for beginning C++ programmers to understand is the difference between passing function parameters by value and passing function parameters by reference. In this article I’m going to explain the difference and demonstrate when and why you should use each parameter type.

C ++初学者最难理解的概念之一是按值传递函数参数和按引用传递函数参数之间的区别。 在本文中,我将解释不同之处,并说明何时以及为什么应使用每种参数类型。

通过定义的值传递 (Pass by Value Defined)

A function parameter is passed by value when the function receives a copy of the parameter. This means the parameter value is stored in the memory reserved for the function call. This is the default behavior of C++.

当函数接收到参数的副本时,将按值传递函数参数。 这意味着参数值存储在为函数调用保留的存储器中。 这是C ++的默认行为。

To demonstrate what passing by value means, here is a simple example:

为了说明按值传递的含义,这是一个简单的示例:

#include <iostream>
using namespace std;void changeParam(int param) {
param += 5;
cout << "Parameter: " << param << endl;
}int main ()
{
int number = 0;
changeParam(number);
cout << "Number: " << number << endl;
return 0;
}

The output from this program is:

该程序的输出为:

Parameter: 5
Number: 0

The variable number is passed as an argument(parameter) to the function. Inside the function, the parameter’s value is increased by 5 and that value is displayed to the screen. The function ends and control passes back to main. The value of number is then accessed and is shown to still be 0.

变量number作为参数(参数)传递给函数。 在函数内部,参数的值增加5,并在屏幕上显示该值。 函数结束,控制权返回给main 。 然后访问number的值,该值仍显示为0。

The variable’s value didn’t change because when number was passed to the function, a copy of its value was placed into the parameter. This value was the value increased by the function body and when the function ended, all the memory associated with the function, which includes the parameter and its value, was erased.

变量的值没有改变,因为当将number传递给函数时,其值的副本已放入参数中。 该值是函数主体增加的值,当函数结束时,与该函数关联的所有存储器(包括参数及其值)都将被擦除。

For the most part, this is exactly the behavior we want from C++ functions. Functions are, indeed, written to perform computations but it becomes harder to understand how a program works when the data passed to a function can be changed by the function.

在大多数情况下,这正是我们想要的C ++函数的行为。 实际上,函数是为执行计算而编写的,但是当传递给函数的数据可以由函数更改时,很难理解程序的工作方式。

通过参考传递定义 (Pass by Reference Defined)

A parameter is passed by reference by preceding the parameter name with the address-of operator (&). When a parameter is passed by reference, the compiler accesses the memory location of the parameter and works directly with that value, rather than with a copy of the value as happens with pass by value parameters.

通过在参数名称前加上地址运算符( & ),以引用方式传递参数。 当通过引用传递参数时,编译器将访问参数的内存位置,并直接使用该值,而不是使用按值传递参数时发生的值副本。

Here is the program above modified to work with a reference parameter rather than a value parameter:

这是上面经过修改以使用参考参数而不是值参数的程序:

void changeParam(int &param) {
param += 5;
cout << "Parameter: " << param << endl;
}int main ()
{
int number = 0;
changeParam(number);
cout << "Number: " << number << endl;
return 0;
}

Here is the output of this program:

这是该程序的输出:

Parameter: 5
Number: 5

Because the parameter was passed by reference, the change made in the function is permanent and when the variable is accessed in main, the new value of number is displayed.

由于参数是通过引用传递的,因此在函数中所做的更改是永久性的,并且在main访问变量时,将显示number的新值。

引用传递的实际示例 (A Practical Example of Pass by Reference)

A good example of a function that needs to make permanent changes to its parameters is a swap function. In a sorting application, swapping variable values can happen hundreds or more times so it makes sense to create a swap function for this.

需要永久更改其参数的函数的一个很好的例子是交换函数。 在排序应用程序中,交换变量值可能会发生数百次或更多次,因此为此创建交换函数是有意义的。

Let’s first look at what happens if we write our swap function using value parameters:

首先让我们看看如果使用值参数编写交换函数会发生什么:

void swap(int val1, int val2) {
int temp = val1;
val1 = val2;
val2 = temp;
}int main ()
{
int number1 = 1;
int number2 = 2;
cout << "number1: " << number1 <<", number2: "
<< number2 << endl;
swap(number1, number2);
cout << "number1: " << number1 <<", number2: "
<< number2 << endl;
return 0;
}

The output from this program is:

该程序的输出为:

number1: 1, number2: 2
number1: 1, number2: 2

The values weren’t swapped because they were passed by value to the function and once the function was over, the values in the variables are the same as they were before being passed to the function.

不会交换值,因为它们是按值传递给函数的,一旦函数结束,变量中的值与传递给函数之前的值相同。

All you must do is make the parameters reference parameters and the function works fine:

您所要做的就是使参数引用参数,并且该函数可以正常运行:

void swap(int &val1, int &val2) {
int temp = val1;
val1 = val2;
val2 = temp;
}int main ()
{
int number1 = 1;
int number2 = 2;
cout << "number1: " << number1 <<", number2: "
<< number2 << endl;
swap(number1, number2);
cout << "number1: " << number1 <<", number2: "
<< number2 << endl;
return 0;
}

The output from this program is:

该程序的输出为:

number1: 1, number2: 2
number1: 2, number2: 1

Clearly, passing by reference fixes the problem and makes variable swapping possible.

显然,通过引用传递解决了该问题,并使变量交换成为可能。

默认情况下,数组是参考参数 (Arrays are Reference Parameters by Default)

Some objects in C++ are reference parameters by default. An example of such an object is the array. You can pass an array to a function without supplying the address-of operator and any changes made to the array in the function are permanent.

默认情况下,C ++中的某些对象是参考参数。 这样的对象的一个​​例子是数组。 您可以在不提供address-of运算符的情况下将数组传递给函数,并且对该函数中的数组所做的任何更改都是永久的。

Here is an example of a function that curves the grades in an array passed to it:

这是一个函数的示例,该函数可以弯曲传递给它的数组中的成绩:

void curver(int arr[], int numEles, int amount) {
for (int i = 0; i < numEles; i++) {
arr[i] += amount;
}
}int main ()
{
const int numElements = 5;
int grades[] = {71, 67, 88, 72, 66};
for (const int grade : grades) {
cout << grade << " ";
}
cout << endl;
curver(grades, numElements, 5);
for (const int grade : grades) {
cout << grade << " ";
}
return 0;
}

Here is the output from this program:

这是该程序的输出:

71 67 88 72 66
76 72 93 77 71

向量默认为值参数 (Vectors are Value Parameters by Default)

Unlike arrays, vectors are value parameters by default and if you want to make changes to a vector in a function, you must pass the vector as a reference parameter using the address-of operator.

与数组不同,矢量默认情况下是值参数,如果要在函数中对矢量进行更改,则必须使用address-of运算符将矢量作为参考参数传递。

Here is the grade example from above rewritten to use a vector instead of an array:

这是上面的成绩示例,改写为使用向量而不是数组:

#include <iostream>
#include <vector>
using namespace std;void curver(vector<int> &vec, int amount) {
for (int i = 0; i < vec.size(); i++) {
vec[i] += 5;
}
}int main ()
{
vector<int> grades = {71, 67, 88, 72, 66};
for (const int grade : grades) {
cout << grade << " ";
}
cout << endl;
curver(grades, 5);
for (const int grade : grades) {
cout << grade << " ";
}
return 0;
}

The output from this program is:

该程序的输出为:

71 67 88 72 66
76 72 93 77 71

The program will run if the vector is passed by value, but the grades will not be changed after the function call.

如果向量通过值传递,则程序将运行,但是函数调用后的等级不会更改。

何时使用每个参数传递类型 (When to Use Each Parameter Passing Type)

In general, the functions you write should be written with parameters that are passed by value. Most functions are written to generate new values from the data that are passed to them. However, there are situations when passing parameters by reference is necessary, such as swapping variable values and modifying vector values.

通常,您编写的函数应使用按值传递的参数来编写。 编写大多数函数是根据传递给它们的数据生成新值。 但是,有些情况下需要通过引用传递参数,例如交换变量值和修改向量值。

Many beginning programmers, however, learn about reference parameters and see them as a solution to every function problem. Don’t make this mistake yourself. Use reference parameters when you must and value parameters the rest of the time.

但是,许多新手程序员了解参考参数并将其视为解决每个函数问题的方法。 不要自己犯这个错误。 必要时使用参考参数,其余时间使用参数值。

Thanks for reading and please email me at mmmcmillan1@att.net with comments and suggestions. If you are interested in my online programming courses, please visit https://learningcpp.teachable.com.

感谢您的阅读,请给我发电子邮件mmmmmillan1@att.net并提供评论和建议。 如果您对我的在线编程课程感兴趣,请访问https://learningcpp.teachable.com

翻译自: https://levelup.gitconnected.com/learning-c-value-and-reference-parameters-d3cbfd176b42

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值