为什么"---"和"+ ++"和"+++"的操作方式不同?



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

我这里有一套在ab之间不同风格的操作:在这里看到它的工作

#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,并从10a中减去。

另外,由于其他四个语句,我认为编译器将它们全部视为---但是看,- --结果的混乱出现了。在这里看到它的工作

解析遵循最大 munch 规则,因此所有减去第三个的语句都被解释为(a--)-ba并返回其先前的值(10)。

第三个是a-(--b)它是b的预递减,因此返回新的递减值。

我认为这是因为最大蒙克规则。来自维基:

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

来自专家 C 编程:

ANSI标准指定了一个被称为最大蒙克策略。马克西马尔·蒙克说,如果还有更多 与下一个令牌的一种可能性相比,编译器更愿意 咬掉涉及最长字符序列的那个。

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

因为--X运算符:

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

因此,--b不可能"事后减少"。它总是"在"之前"这样做。

混乱

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

在另一种情况下,您将其拆分为- --,编译器别无选择:由于中间的空间,它必须将其视为- --。就像-- -一样,这种情况是显而易见的,完全可以看到哪个部分构成了--运算符,编译器必须遵守这一点。

该语句相当于 10-6 = 4, 其余相当于 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;
}

在本系列语句中

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。所以你有等于410 - 6

如果你在所有这些语句中用减号代替加号,你会得到同样的效果

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

因此,这些操作 - -- 和 + ++ 的行为方式相同。

最新更新