函数参数变量是否总是需要一个 & 或 * 运算符?

huangapple go评论112阅读模式
英文:

Do function parameter variables always require a & or * operator?

问题

当在C++中声明函数签名时,会使用地址运算符和解引用运算符,就像下面的示例一样。

int someFunction(std::vector<int>& nums) {
     //做一些操作
}

在这个上下文中,& 用于声明使用 nums 变量的地址而不是值。

如果将此签名更改为下面的方式,则使用的是值而不是地址。

int someFunction(std::vector<int>* nums) {
     //做一些操作
}

但是,如果现在使用下面的方式,我假设仍然使用 nums 变量的值,尽管没有运算符。

int someFunction(std::vector<int> nums) {
     //做一些操作
}

如果这是真的,那么由于缺少运算符和 * 运算符都会产生相同的结果,那么为什么需要 * 运算符呢?它只是为了简洁吗?

英文:

I'm reteaching myself C++ and as I'm reading about pointers a question has came into mind.

When declaring function signatures in C++, the address-of and dereference operators are used, such as the below.

int someFunction(std::vector&lt;int&gt;&amp; nums) {
     //do stuff 
}

In this context the &amp; is being used to declare that the address of the nums variable is being used rather than the value.

If this signature is changed to the below, the value is being used instead.

int someFunction(std::vector&lt;int&gt;* nums) {
     //do stuff 
}

However if the below is now used, I assume the value of the nums variable is still being used despite the lack of operator.

int someFunction(std::vector&lt;int&gt; nums) {
     //do stuff 
}

If this is true, since the lack of an operator and the * operator both result in the same thing, why is there any need for the * operator at all? Is it simply for brevity?

答案1

得分: 2

*&amp; 在你的代码中都不是解引用或取地址运算符。在这里,*&amp; 都是类型的一部分:

int x;      // 声明一个整数
int* p;     // 声明一个整数指针
int&amp; r = x; // 声明一个整数引用

地址取值和解引用运算符在你将值赋给上述变量时才会起作用:

p = &amp;x; // 这里的 &amp; 是地址取值运算符
x = *p; // 这里的 * 是解引用运算符

在这个上下文中,&amp; 表示 nums 是按引用传递的:

int someFunction(std::vector&lt;int&gt;&amp; nums) {
    // 做一些操作
}

不,这里的 &amp; 表示 nums 是按引用传递的。

如果函数签名改为以下形式,那么将使用值而不是引用:

int someFunction(std::vector&lt;int&gt;* nums) {
    // 做一些操作
}

不,这里 nums 被传递为指针。

只有以下函数是按值传递的:

int someFunction(std::vector&lt;int&gt; nums) {
    // 做一些操作
}
英文:

Those * and &amp; in your code are neither dereference nor address-of operators. Both, * and &amp; can have different meanings. Here they are part of the type:

int x;      // declares an int
int* p;     // declares a pointer to int
int&amp; r = x; // declares a reference to int

The address-of and dereference operators come into play for example when you assign something to the above variables:

p = &amp;x; // here &amp; is address-of operator
x = *p; // here * is dereference operator

> int someFunction(std::vector<int>& nums) {
> //do stuff
> }
> In this context the & is being used to declare that the address of the nums variable is being used rather than the value.

No. Here the &amp; means that nums is passed as reference.

> If this signature is changed to the below, the value is being used
> instead.
>
> int someFunction(std::vector<int>* nums) {
> //do stuff
> }

No. Here nums is passed as pointer.

Only this is pass-by-value:

> int someFunction(std::vector<int> nums) {
> //do stuff
> }

答案2

得分: 1

你混淆了一些事情。在C++中,传递给函数的参数会被复制到函数内部。这被称为“按值传递参数”,对于小型类型(如基本类型int、double等)来说是可以的,但对于大型对象来说可能非常昂贵。想象一下,如果你的std::vector有1000万个元素。

在第一种情况下,使用int someFunction(std::vector&lt;int&gt;&amp; nums)中的&amp;告诉编译器你想要通过引用传递参数nums,而不是默认的按值传递。这意味着向函数内部不会复制向量,而是使用引用(这里的成本类似于复制单个指针)。请注意,由于你使用了引用,如果你在函数内修改了nums,这个修改将在函数外部可见(传递给函数的变量将被更改)。有时这是你想要的,有时则不是。如果你想避免复制但不想更改向量,请改用int someFunction(const std::vector&lt;int&gt;&amp; nums)

在第二种情况下,实际上你只是传递了一个指针给函数,而不是std::vector&lt;int&gt;,尽管指针指向了一个std::vector&lt;int&gt;。与前一种情况类似,无论向量有多少元素,只有指针被复制,你对指向的向量所做的任何更改都将在函数外部可见。然而,请注意,指针可以为空,而引用不行。这意味着你需要检查指针是否为空。

第三种情况是默认的“按值传递”,向量会被复制到函数内部。你对向量所做的任何更改都不会在函数外部可见,因为你只是更改了副本。但如果向量有很多元素,成本可能很高。

英文:

You are confusing things. In C++ arguments passed to a function are copied into the function. This is called "passing arguments by value", which is Ok for small types such as primitive types (int, double, etc), but it might be very costly for large objects. Imagine if your std::vector has 10 million elements.

In the first case with int someFunction(std::vector&lt;int&gt;&amp; nums) the &amp; indicates to the compiler that you want to pass the argment nums by reference, instead of the default by value. That means that the vector will not be copied into the function and a reference will be used instead (the cost here is like copying a single pointer). Note that since you are using a reference, if you modify nums inside your function the change will be visible outside the function (the variable passed as argument to the function will be changed). This is sometimes what you want and sometimes it is not. If you want to avoid the copy but don't want to change the vector, use int someFunction(const std::vector&lt;int&gt;&amp; nums) instead.

In the second case you are actually passing just a pointer to the function and not a std::vector&lt;int&gt;, although the pointer points to an std::vector&lt;int&gt;. Similarly to the previous case, only a pointer is copied no matter how many elements the vector has and any change you made the the pointed vector will be visible outside the function. Note, however, that pointers can be null, while references cannot. That means that you would need to check if the pointer is null.

The third case is the default "passing by value" and a vector is copied into the function. Any change you make in the vector will not be visible outside the function, since you only changed the copy. But the cost can be high if the vector as many elements.

huangapple
  • 本文由 发表于 2020年1月6日 20:15:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/59611944.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定