2

请对我放轻松,不要开枪,因为我还是新手。

当我运行这段代码时,我完全糊涂了,终生无法弄清楚为什么:

int y = 9;
cout << "++y = " << ++y << "\n--y = " << --y << "\ny++ = " << y++ << "\ny-- = " << y-- << "\n";
cout << "y = " << y << "\n";

我得到以下结果:

y = 9
++y = 9
--y = 9
y++ = 8
y-- = 9
y = 9

而不是这些结果:

y = 9
++y = 10
--y = 9
y++ = 9
y-- = 10
y = 9

我从这段代码中得到:

int y = 9;
cout << "y = " << y << "\n";
cout << "++y = " << ++y << "\n";
cout << "--y = " << --y << "\n";
cout << "y++ = " << y++ << "\n";
cout << "y-- = " << y-- << "\n";
cout << "y = " << y << "\n";

任何人都可以用尽可能简单的语言解释第一个代码中发生了什么,以便它以这种方式打印结果吗?

4

3 回答 3

11

一个简单的规则是,您不应在任何给定语句中多次增加同一位置。所以你不应该编码cout << y++ << ++y << endl;包含两个增量y(假设int y;声明)。

有关详细信息,请阅读C++标准中的序列点未定义行为。

有很多相关的问题。调查他们更多!

于 2012-01-19T20:07:20.440 回答
3

当按照规则运算*要在+之前,++在*之前,就是这样。

 a*b++ + c // first b++ (returns **old** b), than a*b, than ...+c

但是当你有 a++ * a-- 时,没有人知道,两个操作数中的哪一个,a++ 或 a-- 将首先被计算。根据 ANSII 标准,即使使用相同的翻译器,每次的结果都是不可预知的。

引用 C++ ANSII 标准:

除非另有说明,否则未指定单个运算符的操作数和单个表达式的子表达式的求值顺序,以及副作用发生的顺序。在前一个和下一个序列点之间,一个标量对象的存储值最多只能通过表达式的计算修改一次。此外,只能访问先验值以确定要存储的值。对于完整表达式的子表达式的每个允许排序,都应满足本段的要求;否则行为未定义。[例子:

      i = v[i++];      // the behavior is undefined
      i = 7, i++, i++; // `i' becomes 9

      i = ++i + 1;     // the behavior is undefined 
      i = i + 1;       // the value of 'i' is incremented

序列点:

  • 在完整表达式的评估结束时(完整表达式是表达式语句,或任何其他不是任何更大表达式中的子表达式的表达式);
  • 在 ||、&&、?: 和逗号运算符处;
  • 并在函数调用中(在评估所有参数之后,就在实际调用之前)。

所以,|| 是一个序列点,但 << 不是。

于 2012-01-19T20:10:26.397 回答
2

第一个代码的多行版本应该是:

  y = 9;
  cout << "y-- = " << y-- << "\n";
  cout << "y++ = " << y++ << "\n"
  cout << "--y = " << --y << "\n"
  cout << "++y = " << ++y << "\n"
  cout << "y = " << y << "\n";
于 2012-01-19T20:17:46.930 回答