我正盯着下面的表达,由别人写的:
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 - 我会接受给出我真正想要的答案。
答案 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,则将评估最后一行。
但我感兴趣的是,最后一行是对第一行的否定