【问题标题】:Pointer not showing updated value when incrementing a variable in std::cout [duplicate]在 std::cout 中增加变量时指针未显示更新值 [重复]
【发布时间】:2017-10-05 13:34:29
【问题描述】:
#include <iostream>
#include <string>

using namespace std;

int main()
{
  int a = 5;
  int& b = a;
  int* c = &a;

  cout << "CASE 1" << endl;
  cout << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
  b = 10;
  cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl << endl;

  cout << "CASE 2";
  a = 5;
  cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
  b = 10;
  cout << endl << "a is " << a << endl << "b is " << ++b << endl << "c is " << *c << endl << endl;

  cout << "CASE 3";
  a = 5;
  cout << endl << "a is " << a << endl << "b is " << b << endl << "c is " << *c << endl;
  b = 10;
  cout << endl << "a is " << a << endl << "b is " << b++ << endl << "c is " << *c << endl;
}

输出:

案例 1:

a is 5. b is 5. c is 5.
a is 10. b is 10. c is 10.

案例 2:

a is 5. b is 5. c is 5.

a is 11. b is 11. c is 10.

案例 3:

a is 5. b is 5. c is 5.
a is 11. b is 10. c is 10.

我理解 CASE 1。但我很难理解 CASE 2 和 CASE 3。有人可以解释为什么 c 在这两种情况下都没有更新新值吗?

【问题讨论】:

  • 可以添加输出吗
  • &lt;&lt;的运算顺序未定义。简单地说,operator &lt;&lt; 是一个函数,这些是它的参数。函数的参数可以按任何顺序评估,因为它是实现定义的。
  • 看起来像未定义和/或未指定的行为。甚至可能取决于所使用的 C++ 标准版本。排序规则和运算符优先级的规则几乎是非常复杂的,请参阅en.cppreference.com/w/cpp/language/eval_orderen.cppreference.com/w/cpp/language/operator_precedence。为了避免所有这些麻烦,我个人的规则是永远不要访问在同一表达式中应用了++ 的对象。

标签: c++ pointers operator-precedence


【解决方案1】:

未指定操作数的求值顺序,您正在修改一个对象并读取它,而这些操作没有被排序。

因此,您的程序与cout &lt;&lt; a &lt;&lt; a++; 一样未定义,任何事情都可能发生。

【讨论】:

  • 这有点含糊。 “任何事情都可能发生”使它看起来具有未定义的行为,但只有在使用旧 C++(C++11 之前)时才会如此。 “As undefined as ...”是正确的,但没有帮助;我相信对于 OP 和 cout &lt;&lt; a &lt;&lt; a++ 中的代码,它实际上是“C++03 中的 UB;在 C++11 及更高版本中未指定”。不过我不确定。
  • @anatolyg 操作数评估在 C++11(第 1.9 节,第 15 条)中未排序,导致未定义的行为。我相信 17 会改变这一点。
【解决方案2】:

我认为您的问题是由于所谓的序列点。您可以在 this answer 中详细了解这一点,但简而言之,它基本上说明了表达式元素的顺序或评估。

更新在你的情况下这个顺序是未定义的,尽管一些编译器似乎使它从右到左。

【讨论】:

    猜你喜欢
    • 2015-07-28
    • 2012-09-21
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    相关资源
    最近更新 更多