C++按值传递,不应该将两个变量的内存地址复制并绑定到不同的位置吗?

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

C++ Pass-by-value, shouldn't the memory_addresses of the two variables be copied and binded into different places?

问题

我正在练习C++,遇到了传值和传引用的话题。从BroCode学到的是,当我们通过参数的值调用swap函数时,它们的内存地址将与原始地址不同。

#include <iostream>

using std::cout;
using std::endl;

void swap_byValue(int dog, int cat);
void swap_byReference(int &dog, int &cat);
void print(int dog, int cat);

int main(){
    int dog = 100;
    int cat = 999;

    cout << "*****************************" << endl
         << "*  variable_name  *  value  *      (memory_address)" << endl;

    print(dog, cat);

    swap_byValue(dog, cat);
    print(dog, cat);
    return 0;
}

void swap_byValue(int dog, int cat){
    int temp;
    temp = dog;
    dog = cat;
    cat = temp;
}
void swap_byReference(int &dog, int &cat){
    int temp;
    temp = dog;
    dog = cat;
    cat = temp;
}

void print(int dog, int cat){
    cout << "*****************************" << "----->  " << &dog << endl
         << "*       dog       *   " << dog << "   *" <<endl
         << "*****************************" << "----->  " << &cat << endl
         << "*       cat       *   " << cat << "   *" <<endl;
}

运行后的结果如下:

*****************************
*  variable_name  *  value  *      (memory_address)
*****************************
----->  0x42295ffc30
*       dog       *   100   *
*****************************
----->  0x42295ffc38
*       cat       *   999   *
*****************************
----->  0x42295ffc30
*       dog       *   100   *
*****************************
----->  0x42295ffc38
*       cat       *   999   *

但是,变量dog(交换之前)的内存地址不应该与变量dog(交换之后)的内存地址不同吗?它们现在都是0x42295ffc30。我是否有什么误解或做错了什么?非常感谢。

英文:

I'm practicing C++, and facing the Pass-by-value/reference topic. What I learned from BroCode is that, when we call a swap function by the parameters' value, both of their memory_addresses will be different from the original ones.

#include &lt;iostream&gt;

using std::cout;
using std::endl;

void swap_byValue(int dog, int cat);
void swap_byReference(int &amp;dog, int &amp;cat);
void print(int dog, int cat);

int main(){
    int dog = 100;
    int cat = 999;

    cout &lt;&lt; &quot;*****************************&quot; &lt;&lt; endl
         &lt;&lt; &quot;*  variable_name  *  value  *&quot; &lt;&lt; &quot;      (memory_address)&quot; &lt;&lt; endl;

    print(dog, cat);

    swap_byValue(dog, cat);
    print(dog, cat);
    return 0;
}

void swap_byValue(int dog, int cat){
    int temp;
    temp = dog;
    dog = cat;
    cat = temp;
}
void swap_byReference(int &amp;dog, int &amp;cat){
    int temp;
    temp = dog;
    dog = cat;
    cat = temp;
}

void print(int dog, int cat){
    cout &lt;&lt; &quot;*****************************&quot; &lt;&lt; &quot;-----&gt;  &quot; &lt;&lt; &amp;dog &lt;&lt; endl
         &lt;&lt; &quot;*       dog       *   &quot; &lt;&lt; dog &lt;&lt; &quot;   *&quot; &lt;&lt;endl
         &lt;&lt; &quot;*****************************&quot; &lt;&lt; &quot;-----&gt;  &quot; &lt;&lt; &amp;cat &lt;&lt; endl
         &lt;&lt; &quot;*       cat       *   &quot; &lt;&lt; cat &lt;&lt; &quot;   *&quot; &lt;&lt;endl; 
}

The result after running is down below:

*****************************
*  variable_name  *  value  *      (memory_address)
*****************************-----&gt;  0x42295ffc30
*       dog       *   100   *
*****************************-----&gt;  0x42295ffc38
*       cat       *   999   *
*****************************-----&gt;  0x42295ffc30
*       dog       *   100   *
*****************************-----&gt;  0x42295ffc38
*       cat       *   999   *

But shouldn't the memory-address of variable dog(before swapping) differ from variable dog(after swapping)? They're both 0x42295ffc30 right now. Is there anything I misunderstood or did wrong? Thanks a lot.

答案1

得分: 3

我不会太过关注地址。

当你通过值传递参数时,函数会获得你传递的内容的自己的拷贝。所以当你进行交换时,它只是交换了它自己的这些拷贝值。

当你通过引用传递时,你得到的是原始值的一个别名。所以当你交换它们时,原始值也会被交换。

英文:

I wouldn't think so much in terms of addresses.

When you pass a parameter by value, the function gets its own copy of whatever you passed. So when you do the swap, it just swaps its own copies of the to values.

When you pass by reference, you get something that's basically just an alias for the original value. So when you swap those, the original values get swapped.

答案2

得分: 1

以下是要翻译的内容:

结果如预期。不可能更改对象的地址。例如,可以复制对象,然后您就会得到一个新对象,其地址不同于旧对象,但旧对象地址保持不变。另一方面,引用并不创建新对象,它只是引用原始对象,因此具有相同的地址。

调用void swap_byValue(int dog, int cat)没有任何效果,而void swap_byReference(int &amp;dog, int &amp;cat)交换参数的值。实际上,您应该使用std::swap来交换两个变量的值。

您在print中打印的地址是函数局部变量dogcat的地址。通过使用不同的名称,可以避免混淆:

void print(int a, int b){
    cout << "*****************************" << "---->  " << &a << "\n"
         << "*       a         *   " << a << "   *\n"
         << "*****************************" << "---->  " << &b << "\n"
         << "*       b       *   " << b << "   *\n"; 
}

这将打印两个变量ab的地址,它们是传递给函数的参数的副本。当您多次调用函数时,它们可能会在内存中的相同位置结束。这是可能的,因为在函数返回后它们会消失。

如果您在main中打印dogcat的地址,您还将看到它们在交换后不会改变。

我只能猜测您误解了什么,也许您想要看到这个:

#include <iostream>

void by_value(int x) { std::cout << "by_value: " << &x << "\n"; }
void by_ref(int& y) { std::cout << "by_ref: " << &y << "\n"; }

int main() {
    int z = 42;
    std::cout << "in main: " << &z << "\n";
    by_value(z);
    by_ref(z);
}

可能的输出

in main: 0x7ffca8f5989c
by_value: 0x7ffca8f5987c
by_ref: 0x7ffca8f5989c

main中的zby_ref中的y具有相同的地址,因为它们是同一个对象。y是对z的引用。by_value中的x具有不同的地址,因为它是一个副本。

我从BroCode那里学到的是,当我们通过参数的值调用交换函数时,它们的内存地址都会与原始地址不同。

这是不正确的。

英文:

The results you get are to be expected. It is not possible to change the address of an object. What can be done for example is to copy an object, then you have a new object at a different address and the old object at the same address. A reference on the other hand does not create a new object it merely refers to the original object, hence has the same address.

Calling void swap_byValue(int dog, int cat) has no effect whatsoever and void swap_byReference(int &amp;dog, int &amp;cat) swaps the values of the parameters. What you should actually be using is std::swap to swap values of two variables.

The addresses you print in print are those of the function local variables dog and cat. You can avoid confusion by using distinct names:

void print(int a, int b){
    cout &lt;&lt; &quot;*****************************&quot; &lt;&lt; &quot;-----&gt;  &quot; &lt;&lt; &amp;a &lt;&lt; &quot;\n&quot;
         &lt;&lt; &quot;*       a         *   &quot; &lt;&lt; a &lt;&lt; &quot;   *\n&quot;
         &lt;&lt; &quot;*****************************&quot; &lt;&lt; &quot;-----&gt;  &quot; &lt;&lt; &amp;b &lt;&lt; &quot;\n&quot;
         &lt;&lt; &quot;*       b       *   &quot; &lt;&lt; b &lt;&lt; &quot;   *\n&quot;; 
}

This prints the addresses of the two variables a and b which are copies of the arguments passed to the function. When you call the function twice or more they may happen to end up in the same place in memory. This is possible because after the function returns they are gone.

If you print the addresses of dog and cat in main you will also see that they do not change after swapping.

I can only guess what you misunderstood, perhaps you wanted to see this:

#include &lt;iostream&gt;

void by_value(int x) { std::cout &lt;&lt; &quot;by_value: &quot; &lt;&lt; &amp;x &lt;&lt; &quot;\n&quot;; }
void by_ref(int&amp; y) { std::cout &lt;&lt; &quot;by_ref: &quot; &lt;&lt; &amp;y &lt;&lt; &quot;\n&quot;; }

int main() {
    int z = 42;
    std::cout &lt;&lt; &quot;in main: &quot; &lt;&lt; &amp;z &lt;&lt; &quot;\n&quot;;
    by_value(z);
    by_ref(z);
}

Possible output:

in main: 0x7ffca8f5989c
by_value: 0x7ffca8f5987c
by_ref: 0x7ffca8f5989c

z in main and y in by_ref do have the same address, because its the same object. y is a reference to z. The address of the reference is that of the original object. x in by_value has a different address because it is a copy.

> What I learned from BroCode is that, when we call a swap function by the parameters' value, both of their memory_addresses will be different from the original ones.

That is not correct.

huangapple
  • 本文由 发表于 2023年7月14日 03:37:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76682717.html
匿名

发表评论

匿名网友

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

确定