C++运算符中的空格,有哪些规则?

3
这些表达式中的空格是否有任何含义:
假设:
int a = 1;  
int b = 2;  

1)

int c = a++ +b;

或者, 2)
int c = a+ ++b;

当我在Visual Studio中运行这两个代码时,得到的结果是不同的。这种情况是否符合规范?规范又有什么说法呢?
通常来说,应该先计算后自增还是先计算前自增呢?
编辑:我应该说
c = a+++b;
在Visual Studio上不能编译通过。但我认为它应该可以。似乎是先计算了后缀++。

2
这是正确的行为。 - Jarod42
5
你应该询问这段代码的作用:int c = a+++b; - juanchopanza
2
@acraig5075 是的,但问题是,在这里序列点是无关紧要的。 - juanchopanza
1
一个重要的规则是运算符不能有空格。除此之外,请参见https://dev59.com/8ms05IYBdhLWcg3wDtln。 - juanchopanza
2
@BoBTFish: 你显然不是老FORTRAN程序员。 空格只有在Hollerith常量和引号字符串内才有意义。 你真的可以将FOOBAR()称为FOO BAR()。 - Martin Bonner supports Monica
显示剩余8条评论
3个回答

3

这是正确的行为吗?

是的,它是。 后缀 ++ 首先返回当前值,然后将其递增。所以 int c = a++ +b 的意思是计算出 c 的值作为当前 a 值(取当前 a 值,只有在取完后才递增 a)和 b 之间的和;前缀 ++ 首先递增当前值,然后返回已经递增的值,所以在这种情况下,int c = a+ ++b 的意思是计算 c 的值作为 a 和下一个表达式的返回值之和,即 ++b,这意味着首先递增 b,然后返回。

一般来说,应该先评估哪个,后增量还是前增量?

在这个例子中,不是关于哪个先被评估,而是关于每个操作的含义 - 后缀首先返回值,然后递增它;前缀首先递增值,然后返回它。

希望对你有所帮助


3
也许了解程序的一般架构有助于理解它们是如何被解析的。
简而言之,解析程序(C++或其他)有两个阶段:词法分析器和语法分析器。
词法分析器将文本输入映射到一系列符号。这时空格会被处理,因为它们告诉我们符号在哪里。在某些地方,空格非常重要(例如在intc之间,以避免与符号intc混淆),但在其他地方则不重要(例如在a++之间,因为没有歧义来区分它们)。
第一个例子:
int c = a++ +b;

提供以下符号,每个符号单独一行(不同的实现方式可能会有所不同):

int
c
=
a
++
+
b
;

在另一种情况下:
int c = a+ ++b;

符号改为:
int
c
=
a
+
++
b
;

解析器然后根据某些语法从符号中构建一棵树(抽象语法树,AST)。特别是根据C++语法,加法运算符“+”的优先级低于一元“++”运算符(无论是后缀还是前缀)。这意味着第一个示例在语义上与“(a++) + b”相同,而第二个示例类似于“a+ (++b)”。
对于您的示例,AST将不同,因为空格已经导致在词法分析阶段输出不同。
请注意,不需要在“++”和“+”之间使用空格,因此“a+++b”理论上是可以的,但出于可读性考虑不建议这样做。因此,一些空格对于技术原因很重要,而其他空格对于我们用户来阅读代码也很重要。

a+++b在我的Visual Studio上无法编译。但是在我的GCC上可以编译。看起来后缀++比前缀++优先级高? - user3599803
有趣的是,一些实现会拒绝它(也许这样做是最好的)。关于它编译时的行为:实际上这不是一个优先级问题(这会发生在解析器阶段),而是由于词法分析器阶段的最大匹配规则:该规则在上面链接的相应StackOverflow问题中有解释。 - Ghislain Fourny

2
是的,它们应该是不同的;这种行为是正确的。
你可能会有几个混淆的来源。

这个问题不是关于“操作符中的空格”。你有不同的操作符。如果你要去掉空格,你将得到一个不同的问题。请参见什么是c++中的i+++递增

这也不是关于“后缀递增和前缀递增哪个应该先计算”。它是关于理解后缀递增和前缀递增之间的区别

  • 两者都会递增它们所应用的变量。
  • 但是后缀递增表达式返回递增之前的值。
  • 而前缀递增表达式返回递增之后的值。

也就是说:

//Given:
int a = 1;  
int b = 2; 

//Post-increment
int c = a++ +b; =>
        1 + 2; (and a == 2) =>
        3;

//Pre-increment
int c = a+ ++b; =>
        1 + 3; (and b == 3) =>
        4;

可能会引起混淆的另一件事。您写道:a++ +b;。您可能认为+b是一元运算符+。这是错误的假设,因为您有左右操作数,使得+成为一个二进制加法运算符(如x+y)。
最后一个可能的混淆。您可能想知道为什么:
  • a++ +b中,++是应用于a的后增量运算符。
  • 而在a+ ++b中,它是应用于b的前增量运算符。
原因是++的优先级高于二进制加法+。在两种情况下,都不可能将++应用于+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接