代码之家  ›  专栏  ›  技术社区  ›  David

从左到右表达式计算

  •  5
  • David  · 技术社区  · 16 年前

    在C中,是否保证表达式从左到右进行计算?

    例如:

    myClass = GetClass();  
    if (myClass == null || myClass.Property > 0)  
        continue;
    

    有没有不符合的语言?

    9 回复  |  直到 16 年前
        1
  •  14
  •   Tomalak    16 年前

    您实际上引用了一个称为“短路逻辑表达式”的语言功能:

    这意味着:当逻辑表达式的结果不能再改变时,例如,当表达式的计算结果明确为“真”或“假”时,无论什么,表达式的其余部分都不会被计算。

    例如,C语言、Java或JavaScript这样做,你可以依靠这些语言(回答你的问题)。

    在您的情况下,如果myClass不为空:

    • MyClass == null 计算结果为假
    • 由于它是一个“或”表达式,第二部分仍然可以更改结果,因此对其进行计算
    • myClass.Property > 0 确定最终结果

    如果myClass为空:

    • MyCype==空 计算结果为真
    • 因为它是一个“或”表达式,所以后面的内容并不重要
    • 不再进行评估,最终结果为真

    有些语言不会短路逻辑表达式。经典的vb就是一个例子,这里“myClass.property>0”将被计算出来,如果myClass为空(在vb中称为“Nothing”),则会产生一个错误。

        2
  •  5
  •   Jon Skeet    16 年前

    C 3.0规范第7.11节中描述了短路:

    操作x y对应于 操作x y,除了y是 仅当x不为真时计算。

    所以是的,你很好。

    至于其他语言-我从不喜欢代言 全部的 语言。在vb.net中,可以使用短路的orelse和andalso,但不能使用普通的or和and。

        3
  •  2
  •   Peter Miehle    16 年前

    但要小心:

    如果你有类似的东西

    sprintf(buf,“%s%s”,func1(&var),func2(&var));

    对于var的副作用,它没有被定义(在c中,我不确定评估顺序是否用其他语言定义),在哪个顺序中执行func1()和func2()(这取决于参数以什么顺序(左或右)放在堆栈上并从那里进行评估。

        4
  •  0
  •   unwind    16 年前

    计算顺序取决于运算符,在这种情况下,布尔或( || )被定义为通常所称的 short-circuiting ,使这样的构造工作。

        5
  •  0
  •   Firas Assaad    16 年前

    ADA、Visual Basic和Pascal等语言中的和/或运算符不会短路。它们确实提供了额外的操作符来允许这种功能,比如ADA中的“and then”和“or else”。

        6
  •  0
  •   rgargente Chelsea Urquhart    16 年前

    我不确定,你真的对订单感兴趣还是对短路评估感兴趣?

    我不是100%确定,但据我所知,在C中评估的顺序总是相同的(我假设大多数.NET语言(如果不是全部)。短路评估的工作原理如前面的答案所述。

    但是,在C中,您可以选择不使用简单的运算符(而不是&&)短路。通常,您希望短路,但在这种情况下,您可能希望执行所有评估。

        7
  •  0
  •   S.Lott    16 年前

    巨蟒有短路 or and 运算符。

        8
  •  0
  •   Martijn    16 年前

    在JAVA和Haskell & & &和;

    有趣的是:在Haskell,这是自然的语言(你可以定义你自己的运营商做到这一点),而在爪哇和C是 具体的 对于这两个操作员。

        9
  •  0
  •   Joe Tennies    14 年前

    实际上,短路是其中的一部分,但是您还需要知道语言是否保证对这些内容进行从左到右的评估。例如,C(ANSI、ISO、C99)不保证从左到右的评估。在示例代码中,可以在检查空值之前检查属性的值,或者同时执行这两项操作…大多数编译器不这样做,但是没有什么可以阻止它这样做,并且完全符合规范。它甚至告诉您不要因为这个而编写这样的代码。

    推荐文章