提问人:ian 提问时间:7/14/2023 最后编辑:ian 更新时间:7/15/2023 访问量:89
C++按值传递,难道不应该将两个变量的memory_addresses复制并绑定到不同的位置吗?
C++ Pass-by-value, shouldn't the memory_addresses of the two variables be copied and binded into different places?
问:
我正在练习 C++,并面对按值传递/引用主题。我从 BroCode 中学到的是,当我们通过参数的值调用交换函数时,它们的两个memory_addresses都将与原始函数不同。
#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。我是否误解了什么或做错了什么?多谢。
答:
你得到的结果是意料之中的。无法更改对象的地址。例如,可以做的是复制一个对象,然后您在不同的地址有一个新对象,而旧对象位于同一地址。另一方面,引用不会创建新对象,它只是引用原始对象,因此具有相同的地址。
调用没有任何效果,并且会交换参数的值。您实际应该使用的是交换两个变量的值。void swap_byValue(int dog, int cat)
void swap_byReference(int &dog, int &cat)
std::swap
您打印的地址是函数局部变量和 的地址。您可以通过使用不同的名称来避免混淆:print
dog
cat
void print(int a, int b){
cout << "*****************************" << "-----> " << &a << "\n"
<< "* a * " << a << " *\n"
<< "*****************************" << "-----> " << &b << "\n"
<< "* b * " << b << " *\n";
}
这将打印两个变量的地址,它们是传递给函数的参数的副本。当您调用该函数两次或更多次时,它们可能会碰巧最终位于内存中的同一位置。这是可能的,因为在函数返回后,它们就消失了。a
b
如果打印 和 in 的地址,您还将看到它们在交换后不会更改。dog
cat
main
我只能猜到你误会了什么,也许你想看这个:
#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
z
in 和 in 确实具有相同的地址,因为它是同一个对象。 是对 的引用。引用的地址是原始对象的地址。 in 具有不同的地址,因为它是副本。main
y
by_ref
y
z
x
by_value
我从 BroCode 中学到的是,当我们通过参数的值调用交换函数时,它们的两个memory_addresses都将与原始函数不同。
这是不正确的。
评论
我不会在地址方面考虑那么多。
当您按值传递参数时,该函数将获得您传递的任何参数的副本。因此,当您进行交换时,它只是交换自己的 to 值副本。
当你通过引用传递时,你得到的东西基本上只是原始值的别名。因此,当您交换这些值时,原始值会被交换。
评论
void swap_byValue(int dog, int cat)
根本没有任何效果,甚至可能被编译器优化掉。 输出任意堆栈地址。print()
dog
swap_byValue
main
dog
swap_byReference
dog
main