【问题标题】:cout value without touching variable C++cout 值而不接触变量 C++
【发布时间】:2023-03-26 23:29:02
【问题描述】:

当我运行程序时,它会打印变量 a 的值。但是当我评论“cout<<&b<<endl<<&a<<endl;”行时,它会打印一个垃圾值。 背后的解释是什么?

#include<iostream>
using namespace std;

int main()
{
    int a = 9;
    int b = 10;
    int *pb = &b;
    cout<<&b<<endl<<&a<<endl;
    cout<<*(pb+1);
}

【问题讨论】:

  • 未定义的行为 - *(pb+1); 访问“越界”
  • 这是未定义的行为,一切正常。调用约定与此有什么关系
  • 因为pb 指向一个单个 int 变量。当您执行*(pb+1) 时,它等于pb[1],它试图将pb 用作数组并打印数组中的second 值。这超出了pb 指向的范围并导致未定义的行为。未定义的行为会使您的整个程序格式错误且无效。
  • 这不是问题,但您真的需要std::endl 需要的额外内容吗? '\n' 结束一行。

标签: c++ stack calling-convention


【解决方案1】:

屏幕上的垃圾值是 a 和 b 的地址。你应该试试这个:

int *pb = &b;

【讨论】:

  • 你是对的,这个cout &lt;&lt; &amp;b &lt;&lt; endl &lt;&lt; &amp;a &lt;&lt; endl; 将打印ab 的地址,但是无论你试图用这个“答案”实现什么,只会产生编译器错误。
  • 累积。对于这个人只是问背后的解释,而不是问任何错误的问题!
  • 你应该试试这个:int *pb-&gt;&amp;b; 你的意思是语法无效,会产生编译错误!顺便提一句。我什至不确定你想在那里提出什么建议。
  • 我只是提供了将值分配给指针的正确语法。
  • error: expected unqualified-id before ‘&’ token *pb->&b; 正如我所说,这是不正确的语法。如果你想给一个指针赋值,你可以像 int *pb = &amp;b 那样做。一直都是这样。
【解决方案2】:

有两个地方可以得到“乱码”值,但实际上只有一个地方是打印出垃圾的地方。

这个cout &lt;&lt; &amp;b &lt;&lt; endl &lt;&lt; &amp;a &lt;&lt; endl; 将使用address-of-operator 打印ab 的地址。您看到的不是ab 的值,而是它们存储在内存中的位置。这些是十六进制值,每次运行程序时它们可能都会改变。这是预期的行为。

然后是这个构造:*(pb + 1),它实际上是在调用未定义的行为。但这是为什么呢?首先pb是一个指针,所以它存储一个地址,更具体地说是存储b的内存地址。您可以直接打印出pb,这将产生与cout &lt;&lt; &amp;b 相同的结果,或者使用取消引用运算符* 取消引用它。所以这个cout &lt;&lt; *pb 将打印值而不是pb 指向的地址(10 btw)。现在你的陈述有什么问题 - (pb + 1) 没有增加pb 指向的值,而是存储在pb 中的地址。所以它不再指向b 的值,而是指向内存中某处的某个其他值。然后你取消引用这个地址并读取一些随机值——这是你的“垃圾”值。

您可能想要增加pb 指向的值。所以cout &lt;&lt; (*pb + 1) 将打印11(注意括号的位置)。但是cout &lt;&lt; b 仍然会导致10。如果你想真正改变 b 的值,你可以这样做:

int b = 10;
int *pb = &b;
*pb += 1;
cout << b;

现在b 增加了 1 而不触及 b 本身。

【讨论】:

    【解决方案3】:

    当您打印ab 的地址时,这会强制变量实际具有内存地址。否则,一个值可能会存储在寄存器中,或者如果从未使用过则根本不存储。

    编译器转换是一种很常见的优化

    const int a = 9;
    cout << a;
    

    进入

    cout << 9;
    

    永远不要在任何地方存储a

    无论如何,没有规则说明变量在内存中的存储位置和顺序。这完全取决于编译器。所以你对&amp;a == &amp;b + 1(或&amp;b - 1)的假设是无效的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-17
      • 1970-01-01
      相关资源
      最近更新 更多