void foo(int arr2[5], int* x2_ptr) {
x2_ptr = &arr2[4];
cout << *x2_ptr << endl;
return;
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
int x = 9;
int* x_ptr = &x;
foo(arr, x_ptr);
cout << *x_ptr << endl;
return 0;
}
我认为这会打印出5
和5
,但事实证明它会打印5
和9
。因此,当指针 x_ptr
传递给函数 foo()
时,它是否实际创建了一个 NEW POINTER x_ptr2
?我发现这很奇怪,因为我认为指针 x_ptr
本身已通过,然后对x_ptr2
的任何更改都会更改x_ptr
。这背后的确切机制是什么?
答案 0 :(得分:1)
您不是更改指向数据而是更改指针本身的值。要更改指针,
*x2_ptr = arr2[4]
哪会做你想的。分配x2_ptr
指向的位置arr2[4]
处的值。 x2_ptr
是函数的本地变量,它存储内存地址。
你可以:
x2_ptr
的值更改为指向其他地方x2_ptr
指向的值,因此更改为变量如果你仍然无法想象它是如何运作的那样:
x2_ptr
--------------
| 0x12345678 | -----> 9
--------------
如果你x2_ptr = &arr2[4]
获得了
x2_ptr
--------------
| 0xabcdef01 | -----> 5
--------------
因此您要更改存储在变量中的内存地址,使其指向其他位置。指针存储不同的attress但没有更改值。
如果你做*x2_ptr = arr2[4]
而不是有效的
x2_ptr
--------------
| 0x12345678 | -----> 5
--------------
因此您要修改地址0x12345678处的值,从而修改原始值。
答案 1 :(得分:1)
指针被复制,但原始指针及其副本都指向同一地址。这样,当取消引用复制的指针时,获得原始值。
例如,如果指针A位于地址1000,并且它指向位于地址500的值,则其副本将位于1000之外的地址(A的地址),但仍然引用一个值位于地址500.
答案 2 :(得分:0)
正如其他人所指出的那样(原谅双关语):你有两个不同的指针,最初指向同一个位置。这就是为什么如果你用任何一个指针改变int值指向,它会反映在两个地方;但更改指针指向的 where 不会。 指针已复制,但指向的位置不是。
根据您的其他意见和问题,我相信您正在寻找的内容如下:
//replace
void foo(int arr2[5], int* x2_ptr)
//with
void foo(int arr2[5], int*& x2_ptr)
即。您想要一个&
类型的引用(int*
)参数。如果没有引用,您将获得指针的副本,而指针本身的本地更改不会影响源。通过在解除引用指针之后更改指向值的效果并且认为通过以下方式更改,不会混淆非常重要值指针变量可能是相同的。
Jack有关于使用指向指针(即**
)的评论,如果你正确实现它,它也会起作用。但是引用指针*&
更明确地表达了你的意图。
然而,无论哪种方式,这都不是你应该经常做的事情。您基本上是添加一个间接级别来访问感兴趣的“真实”值, int
。所以我想知道你是否想要解决XY problem。
答案 3 :(得分:0)
不是将变量的副本传递给函数,而是传递变量的地址,允许函数的代码使用dereference opearator访问它。