关于将指针作为参数传递给函数:它是否实际在函数中创建了一个新指针?

时间:2017-12-14 02:22:59

标签: c++ pointers

    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;
    }

我认为这会打印出55,但事实证明它会打印59。因此,当指针 x_ptr传递给函数 foo()时,它是否实际创建了一个 NEW POINTER x_ptr2?我发现这很奇怪,因为我认为指针 x_ptr本身已通过,然后对x_ptr2的任何更改都会更改x_ptr。这背后的确切机制是什么?

4 个答案:

答案 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访问它。