【问题标题】:Increment Operator in arrays C++ [duplicate]数组C ++中的增量运算符[重复]
【发布时间】:2015-09-25 06:12:48
【问题描述】:

以下代码给出的输出为:ccb

int t = 0;
char a[] = {'a', 'b', 'c'};
cout<<a[t]<<a[++t]<<a[++t];

我想知道,在生成指定输出的这段代码中实际发生了什么。任何帮助将不胜感激。

【问题讨论】:

  • 第二个++t保证在第一个++t之后被评估。
  • @zenith,你能提供一个说明这一点的来源吗?
  • @Mox C++ 标准。两个++ts 之间没有序列点,因此它们的评估顺序未指定。
  • @zenith,cout &lt;&lt; a[t] 有一个序列点,因为它涉及函数调用。由于重载了 cout << a[t] << a[++t] << a[++t] 等效于 ((cout &lt;&lt; a[t]) &lt;&lt; a[++t]) &lt;&lt; a[++t]。 OP看到的输出可能是t的未初始化值或访问a越界引起的。
  • 它是无序的,因为它类似于f(a,f(b,f(c,d)))。但这值得 IMO 回答。

标签: c++ arrays post-increment pre-increment


【解决方案1】:

我的第一反应:C++ 不保证像

这样的语句的求值顺序
cout<<a[t]<<a[++t]<<a[++t];

您需要按照以下方式做一些事情:

cout<<a[t]<<a[t + 1]<<a[t + 2];
t += 3;

经过进一步审查,响应 R Sahu 的 cmets(谢谢): 评估顺序实际上可能是确定的,因为运算符 t++ 操作按从右到左的顺序执行,因为必须在调用之前评估每个函数调用的参数。 IE。这句话其实是:

cout ( << a[t] ( << a[++t] ( << a[++t] ) ) ) ;

最里面的短语首先被评估。

当然,上面带括号的表达式是无效的。为了技术上正确,我应该说:

operator << (operator << ( operator << ( cout, a[++t]), a[++t]), a[t]);

但这很令人困惑,因为为了以这种形式编写表达式,我必须颠倒索引运算符的顺序(这是编译器所做的)。

最后回应 Baum 的 cmets:即使以这种方式将其分解为函数调用也不会使调用确定,因为未指定评估函数参数的顺序,因此它可以在评估 operator &lt;&lt; (cout, a[++t]) 之前评估 a[t]

在复杂语句中避免具有副作用的操作的解决方案仍然有效。

【讨论】:

  • 我不认为这是正确的。当运算符重载时,评估顺序是非常确定的。 OP看到的输出可能是t的未初始化值或访问a越界引起的。
  • 它可能是确定性的,但并不像预期的那样。我刚刚用 VC 尝试过,参数是从右到左计算的,所以假设从零开始,t[0] 出现在输出的最后。
  • @RSahu 我不这么认为。即使运算符重载,这也类似于f(f(f(cout, t), ++t), ++t),并且函数参数的评估没有顺序。但这应该解释一下。
  • 没有。在operator &lt;&lt; ( operator &lt;&lt; ( cout, a[++t]), a[++t]) 中,operator &lt;&lt; ( cout, a[++t]) 既不在, a[++t]) 之前也不在之后排序。
【解决方案2】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-08
    • 2014-01-19
    • 2017-07-06
    • 2015-08-10
    • 2023-03-26
    • 2012-11-23
    • 1970-01-01
    • 2010-12-29
    相关资源
    最近更新 更多