这个if语句的运算符优先级是什么?

时间:2015-12-21 16:08:06

标签: c++ operator-precedence

我正盯着下面的表达,由别人写的:

if (variableA == CaseA && GetCase(variableB) == CaseA && GetCase(variableC) == CaseA && !CaseB(variableB) || variableA != CaseA)
{
    // do stuff
}

真正让我感到沮丧的是:

!CaseB(variableB) || variableA != CaseA

因为没有任何括号可以将条件组合在一起。

C ++编译器如何评估这些if语句?如果其中一个AND运算符的计算结果为false,这是否意味着由于短路而不会检查OR?

修改

哇,我猜仇恨者今天真想讨厌,考虑到每个答案的下注量除了-4(并计算?)之外。而且,呃,为什么没有实际的解释?洛尔。

保持优雅,人。保持优雅。 ;)

为了记录,简单地说明“从左到右评价”并没有在提供问题的有效答案方面说得太多。在发布之前,我确实使用了Google的强大功能(这也是我在这里发布的一些帖子)。

我承认我在这里的错误没有提及,虽然我认为C ++参考是作为答案的补充发布的最自然的链接,但我能够得到的最好的信息是无意中来自{ {3}},通过源代码示例中的以下引用:

|| has lower precedence than &&

这可以说是模糊的,因为“较低的优先级”实际上并没有根据在这种情况下的含义来规定。

无论哪种方式,对于那些真正贡献你的人都会得到一个upvote - 我会接受给出我真正想要的答案。

4 个答案:

答案 0 :(得分:0)

运营商&&的优先级高于运营商|| seen here,因此所有&&将首先出现,最后是||,换句话说如果我添加了括号

if ((variableA == CaseA && GetCase(variableB) == CaseA && GetCase(variableC) == CaseA && !CaseB(variableB)) || variableA != CaseA)

所以基本上

if (all_the_ands || variableA != CaseA)

如果该表达式的左侧是true,则右侧将因短路而无法执行。

答案 1 :(得分:0)

在您的示例中,运算符优先级如下所示。

! > ==> &安培;&安培; > ||

因此,首先评估的陈述将是

1)!CaseB(variableB)仅当所有其他“&&”条件恰好是真的。如果“variableA == CaseA&& GetCase(variableB)== CaseA&& GetCase(variableC)== CaseA”中的任何一个是假的,那么这里就会发生短路并且“!CaseB( variableB)“将不会执行。

之后,

2)如果条件1)为真,再次短路(正如你猜测的那样),否则“||”条件将被评估。

你是对的,如果条件2)恰好是真的,其他或(||)条件甚至不会因为短路而被检查。

答案 2 :(得分:0)

http://en.cppreference.com/w/cpp/language/operator_precedence

优先级由Sachin Goyal的答案中列出(并在上面的链接中更清楚地列出)。

让您感到困惑的具体优先级细节是!直接与CaseB(variableB)关联,而不是更大的关联。

序列在每个&&||上从左到右进行短路。

如果您询问的!CaseB(variableB) || variableA != CaseA左侧的表达式为false,则会跳过!CaseB(variableB)并评估variableA != CaseA。但如果前面的表达式为真,它使用!CaseB(variableB)的值来决定是否评估其余的。

初始测试variableA == CaseA与最终测试variableA != CaseA的组合似乎很混乱。它可能意味着什么是预期的,但可以更简单地完成。

当您对(X && Y && Z)进行编码时,其含义为((X && Y) && Z),但由于&&的行为方式,这与(X && (Y && Z))相同。所以variableA == CaseA就像&& s的其余操作数上的守卫一样,所以当false||时,你会一直跳到true的另一边。并进行相反的测试并最终解析variableA != CaseA ||。因此,只需从DECLARE @RecordsRequired INT = 5; DECLARE @BaseDateTime SMALLDATETIME = GETDATE(); WITH [Sample] AS ( /* This CTE uses recursion to create the required number of * records. */ SELECT 1 AS RowNumber, @BaseDateTime AS [DateTime] UNION ALL SELECT RowNumber + 1 AS RowNumber, DATEADD(HOUR, 2, [DateTime]) AS [DateTime] FROM [Sample] WHERE RowNumber < @RecordsRequired ) SELECT RowNumber, [DateTime] FROM [Sample] ;

开始就可以更简单地获得相同的效果

答案 3 :(得分:0)

表达式相当于:

( (variableA == CaseA) && 
  (GetCase(variableB) == CaseA) && 
  (GetCase(variableC) == CaseA) && 
  (!CaseB(variableB))
) 
 || 
(variableA != CaseA)

表达式将从上到下进行评估(由于短路规则),如果前四行中的任何一行返回false,则不会评估前四行中的任何一行。如果(且仅当)前四行中的一行返回false,则将评估最后一行。

但我感兴趣的是,最后一行是对第一行的否定

相关问题