【问题标题】:Why does "- --" and "+ ++" and operate differently?为什么“---”和“+++”和操作不同?
【发布时间】:2014-04-04 12:04:33
【问题描述】:

递减/递增是一项基本操作,但它在- --+ ++ 上的优先级让我感到困惑。我将使用递减来说明:

我这里有一套ab之间不同风格的操作:See it working here

#include <iostream>
using namespace std;
int a=10, b=7;
int main() {
// - and -- opearator                         // Results:  Details:
    a = 10, b = 7; cout << a---b << endl;     //    3      a post-decrement        
    a = 10, b = 7; cout << a ---b << endl;    //    3      a post-decrement     
    a = 10, b = 7; cout << a- --b << endl;    //    4      b pre-decrement    
    a = 10, b = 7; cout << a-- -b << endl;    //    3      a post-decrement  
    a = 10, b = 7; cout << a--- b << endl;    //    3      a post-decrement 
    return 0;
    }

我知道4 输出来自递减的b,即7,它变为6,并从a 中减去,即10

另外,由于其他四个语句,我认为编译器将它们都视为---,但看哪,- -- 结果的混乱出现了。 See it working here

【问题讨论】:

  • “语句后的详细信息”列中的所有位都是错误的。所有这些都减少了一个变量。
  • 尝试将操作放在自己的语句中,这样前缀/后缀就不会混淆结果。例如。 auto const x = a---b; std::cout &lt;&lt; x &lt;&lt; ", " &lt;&lt; a &lt;&lt; ", " &lt;&lt; b &lt;&lt; "\n";
  • 另见“走向”运算符--&gt;
  • @hvd 我的意思是我从 echo 得到的结果
  • 链接示例重复打印出a 的值,同时将其标记为“b”。如果你修复它,让它实际打印出b 的值,你会发现程序的行为没有什么特别令人惊讶或令人困惑的,而且解析-+ 之间没有区别。

标签: c++ increment operator-precedence decrement


【解决方案1】:

该语句等价于 10-6 = 4, rest 等价于 9-7 = 3。

#include <iostream>
using namespace std;
int a=10, b=7;
int main() {
    // - and -- opearator               //  Results:  Details after a statement:
    cout << (a--)-b << endl; a=10, b=7;   //    3       Both a and b decremented
    cout << (a --)-b << endl; a=10, b=7;  //    3       Both a and b decremented 
    cout << a- (--b) << endl; a=10, b=7;  //    4       Neither a or b decremented
    cout << (a--) -b << endl; a=10, b=7;  //    3       Both a and b decremented
    cout << (a--)- b << endl; a=10, b=7;  //    3       Both a and b decremented
    return 0;
}

【讨论】:

  • 它是递减的,因此混乱:)
【解决方案2】:

但是为什么在它的声明之后它没有减少呢?

因为--X 运算符:

  • 首先执行递减
  • 然后返回递减的结果

所以,--b 不可能“事后递减”。它总是在“之前”做。

混乱

仔细看代码和结果:每次---不带空格,结果都是一样的:三个。三也是-- - 案例的结果。即使纯粹猜测,您也可以说编译器将其解析为-- -。事实上,它确实是这样做的,因为 C++ 标准要求它这样做。有关“最大咀嚼”规则,请参阅 cmets。其他多字符运算符也是如此,例如++

在将其拆分为- -- 的另一种情况下,编译器别无选择:由于中间有空格,它不得不将其按字面意思视为- --。就像-- - 一样,这种情况是显而易见的,并且完全可见哪个部分构成了-- 运算符,编译器必须遵守这一点。

【讨论】:

  • 是的,确实如此。我只是试着用普通话来解释。
  • --b 之后可能会递减。关键是 --b 的计算结果为 (b-1) 。没有隐含的副作用排序。
【解决方案3】:

解析遵循ma​​ximal munch rule,因此所有语句减去第三个都被解释为(a--)-b,它递减a并返回其先前的值(即10)。

第三个是a-(--b),它是b的预减量,所以返回新的减量值。

【讨论】:

  • @Daniel 没有,你是怎么收集到的?
【解决方案4】:

我认为这是因为Maximal Munch Rule。来自维基:

在计算机编程和计算机科学中,“最大咀嚼”或 “最长匹配”是在创建某些构造时的原则,如 应该消耗尽可能多的可用输入。

来自Expert C Programming

ANSI 标准指定了一种约定,后来被称为 最大咀嚼策略。最大的蒙克说,如果有更多 与下一个标记的一种可能性相比,编译器更愿意 咬掉涉及最长字符序列的那个。

【讨论】:

    【解决方案5】:

    在这一系列的陈述中

    cout << a---b << endl; a=10, b=7;   //    3       Both a and b decremented
    cout << a ---b << endl; a=10, b=7;  //    3       Both a and b decremented 
    cout << a- --b << endl; a=10, b=7;  //    4       Neither a or b decremented
    cout << a-- -b << endl; a=10, b=7;  //    3       Both a and b decremented
    cout << a--- b << endl; a=10, b=7;  //    3       Both a and b decremented
    

    你忘了再包含一条语句:)

    cout << a --- b << endl; a=10, b=7;  //    3       Both a and b decremented
    

    在所有这些陈述中

    cout << a---b << endl; a=10, b=7;   //    3       Both a and b decremented
    cout << a ---b << endl; a=10, b=7;  //    3       Both a and b decremented 
    cout << a--- b << endl; a=10, b=7;  //    3       Both a and b decremented
    cout << a --- b << endl; a=10, b=7;  //    3       Both a and b decremented
    

    编译器将输出的表达式解析为

    a-- -b
    

    那就是它试图提取最长的有效令牌。

    后减运算符的值,例如a--,是其操作数减前的值。所以在表达中

    a-- -b
    

    a-- 的值为 10,b 的值为7。差值等于3

    你有唯一的带有预减运算符的表达式

    cout << a- --b << endl; a=10, b=7;  //    4       Neither a or b decremented
    

    --b 的值是b 递减后的值,即6。所以你有10 - 6 等于4

    如果您将所有这些语句中的减号替换为加号,您将获得相同的效果

    17
    17
    18
    17
    17
    17  // this corresponds to my added statement a +++ b
    

    所以这些操作 - -- 和 + ++ 的行为本质上是相同的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 2012-12-27
      • 2020-04-29
      • 2021-03-28
      相关资源
      最近更新 更多