【问题标题】:c++ spaces in operators , what are the rules运算符中的c ++空格,规则是什么
【发布时间】:2017-06-28 18:50:13
【问题描述】:

这些表达式中的空格是否有任何意义:
假设:

int a = 1;  
int b = 2;  

1)

int c = a++ +b;

或者,
2)

int c = a+ ++b;

当我在 Visual Studio 中运行这两个时,我得到了不同的结果。这是正确的行为吗?规范是怎么说的?
一般来说,应该先评估什么,后增量还是前增量?

编辑:我应该这么说
c =a+++b;
不在 Visual Studio 上编译。但我认为应该。 postfix++ 似乎首先被评估。

【问题讨论】:

  • 这是正确的行为。
  • 你应该问这是做什么的:int c = a+++b;
  • @acraig5075 是的,但问题是,序列点在这里无关紧要。
  • 一个重要的规则是运算符不能有空格。除此之外,请参阅stackoverflow.com/questions/7485088/…
  • @BoBTFish :您显然不是 FORTRAN 的老程序员。过去,空格仅在 Hollerith 常量和带引号的字符串中相关。您真的可以将 FOOBAR() 称为 FOO BAR()。

标签: c++ operators spaces post-increment pre-increment


【解决方案1】:

这是正确的行为吗

是的,是的。 Postfix ++ 首先返回当前值,然后递增它。所以int c = a++ +b 表示将c 的值计算为当前a(取当前a 值,并且只有在取它之后,才增加a)和b 之间的总和; Prefix ++ 首先递增当前值,然后返回已经递增的值,所以在这种情况下,int c = a+ ++b 表示将 c 计算为 a 与下一个表达式 ++b 的返回之间的和,这意味着 b 首先递增,然后返回。

一般来说,应该首先评估什么,后增量或 预增量?

在这个例子中,它不是关于哪个首先被评估,而是关于每个人做什么——后缀首先返回值,然后增加它; prefix 首先增加值,然后返回它。

【讨论】:

    【解决方案2】:

    也许它有助于理解如何解析程序的一般架构。

    简而言之,解析程序(C++ 或其他)有两个阶段:词法分析器和解析器。

    lexer 获取文本输入并将其映射到一系列符号。这是处理空格的时候,因为它们告诉符号在哪里。空格在某些地方确实很重要(例如在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+++btheoretically be fine,但为了便于阅读,不建议这样做。因此,有些空间出于技术原因很重要,而另一些空间对于我们用户阅读代码很重要。

    【讨论】:

    • a+++b 无法在我的 Visual Studio 上编译。但是在我的 gcc 上编译。似乎后缀 ++ 优先于前缀 ++ ?
    • 有趣的是,有些实现拒绝它(也许是最好的)。关于编译时的行为:这实际上不是优先级问题(这将在解析器阶段发生),而是由于词法分析器阶段的最大咀嚼规则:此规则在相应的 StackOverflow 问题中进行了解释,链接在上面的最后一段。
    【解决方案3】:

    是的,它们应该不同;行为是正确的。
    您的困惑有几个可能的原因。


    这个问题与“运算符中的空格”无关。你有不同的运营商。如果您要删除该空间,您会有不同的问题。见What is i+++ increment in c++

    这也不是关于“应该首先评估什么,后增量或前增量”。这是关于理解 后增量和前增量之间的区别。

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

    //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 的预增量运算符。

    原因是++ 的优先级高于二元加法 +。在这两种情况下,都无法将++ 应用于+

    【讨论】:

      猜你喜欢
      • 2013-07-01
      • 2011-12-27
      • 1970-01-01
      • 2017-11-21
      • 2010-12-11
      相关资源
      最近更新 更多