【问题标题】:Reference variable to a pointer指针的引用变量
【发布时间】:2014-01-15 16:25:55
【问题描述】:
int main() {

    int x=10;
    int *p=&x;
    int &y =*p;

    cout<< x << endl << &x <<endl;
    cout<< *p << endl << p <<endl;
    cout<< y << endl << &y <<endl;

    p++;
   *p = 20;

   cout<< x << endl << &x <<endl;
   cout<< *p << endl << p <<endl;
   cout<< y <<endl<< &y <<endl;

   return 0;
}

以上是最能解释我的问题的代码。通常,变量引用 (&) 获取变量的地址并开始引用该变量。我试过通过指针做同样的事情。我定义了一个变量,指针 p 指向 x,引用变量 y 指向 *p。这是否意味着 y 现在指的是同一个变量 x ? 下一步,我停止通过 *p 指向 x,现在引用变量 y 会发生什么?它会持有什么。 在上面的代码中,cout

谁能帮忙解释一下这里的行为。

【问题讨论】:

  • @Pilot no,int *const y = p,访问语法不同
  • @Andrey yes....ref 是 const 指针
  • Normally, a variable reference (&amp;) takes the address of a variable and starts referring to the same 不要以这种方式开始考虑引用。
  • @Pilot:不要以这种方式开始考虑引用。如果您已经开始,停止
  • @LightnessRacesinOrbit 你能解释一下已经开始是什么意思,停止

标签: c++ pointers reference


【解决方案1】:

[注意:此答案仅与 C++ 有关。在 C 中,您的代码不应该编译。]

是的,在你初始化y之后,它指的是x。递增 p 不会改变这一点 -- y 仍然指的是 x

不幸的是,当您执行p++; *p=20; 时,您已经修改了p,因此它不再引用任何已分配的存储空间。当您写入它时,您会得到未定义的行为。这意味着程序停止(或基本上做任何其他事情)是完全合理的。

但是请注意,增加p 是完全允许的——在这方面,x 就像一个包含一个元素的数组,并且明确允许形成指向数组最后一个元素的指针。只有当您写入 到指针所指的地址时,您才会得到未定义的行为。 (即:p++; 可以;*p=20; 不行)。

【讨论】:

  • 在我的机器中(gcccout&lt;&lt;yp++ 之后不工作,意味着在p++ 之后不打印任何内容。请解释一下。
  • y 应该仍然持有 10,将 p++; 替换为 p = new int; 以查看
  • @AJ.:如果您刚刚完成了p++(并且不是 *p=20;),那么cout &lt;&lt; y; 应该可以正常工作。一旦您执行*p=20;,您就会有未定义的行为,并且不再有任何方法可以解释任何事情。
【解决方案2】:
int &y =*p;

在 C++ 中有效。但是在 C 中,它是无效的并且会给你编译时错误。

这是否意味着 y 现在指的是同一个变量 x?

在 C++ 中,是的。但是在递增p 时,它不再指向变量x,而是指向某个未分配的内存位置。写入此位置会调用未定义的行为。现在任何事情都有可能发生。

【讨论】:

  • 就目前而言,这个答案是不正确的。递增p 使其指向未分配的内存具有标准中明确定义的行为。未定义的行为仅在您写入指针所指的位置时才会发生。
  • 由于p++; *P .. ,它不会工作,你应该得到一个错误。试试p = new int;
  • @JerryCoffin;是的。现已编辑。
  • @user3125280;编辑了答案。
  • @hacks 对我来说看起来不错,我只是建议对 OP 进行更改
【解决方案3】:

C 中没有引用类型。addressof 运算符不相同是在 C++ 中声明引用。

这不会在 C 中编译:

int main()
{
    int j = 0;
    int& i = j;
}

当你这样做时:

p++;
*p = 20; // undefined behavior

p 不再指向有效内存。您必须为指向的指针分配内存。

在C++中,如果你修改y,它会修改*p

#include <iostream>

int main()
{
    int x=10;
    int *p=&x;
    int &y =*p; // y becomes a reference to x
    y = 20;
    std::cout << y << " " << *p << " " << x;
}

【讨论】:

    【解决方案4】:

    这将为您提供您所期望的行为

    p = new int;
    *p = 20;
    y = *p;
    

    引用分配给一个 int - x 。它不知道你的意思是 p 指向的那个。它只知道你希望它引用 p 指向的那个 当你分配给引用时。

    【讨论】:

      【解决方案5】:

      请记住,C++ 中的引用只不过是变相的指针。因此,您的代码

      int x=10;
      int *p=&x;
      int &y =*p;
      
      cout<< y <<endl<< &y <<endl;
      p++;
      *p = 20;
      cout<< y <<endl<< &y <<endl;
      

      完全等价于

      int x=10;
      int *p=&x;
      int *y = &*p;
      
      cout<< *y <<endl<< &*y <<endl;
      p++;
      *p = 20;
      cout<< *y <<endl<< &*y <<endl;
      

      现在,您希望这段代码打印什么?您既没有修改 y 也没有修改它指向的值,因此两个 print 语句将输出相同的内容。


      注意
      我在转换后的代码中留下了&amp;*y 组合,以便清楚地了解我是如何转换代码的。当然,&amp;*y 等价于y,所以更易读的等价版本是:

      int x=10;
      int *p=&x;
      int *y = p;
      
      cout<< *y <<endl<< y <<endl;
      p++;
      *p = 20;
      cout<< *y <<endl<< y <<endl;
      

      旁边
      在 C 中,&amp;*y 始终与 y 相同,在 C++ 中则不必如此。在上面的例子中。但是,如果y 是重载operator * 的类型(智能指针会这样做),则&amp;*y 不等于y。对于智能指针,&amp;*y 将返回一个裸指针,指向智能指针所指向的对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-03
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多