&& 的哪一侧(左或右) (and) 运算符在 C++ 中计算
and && 的顺序是? 例如,
以下代码
if (float alpha = value1-value2 && alpha > 0.001)
//do something
引发了一个异常,即 alpha 正在使用但未启动。 我认为 && 左边的表达式是总是会首先启动 alpha 的值,但看来我可能是错的
有什么想法吗?
谢谢
Which order is the and && operator evaluated
For example the following code
if (float alpha = value1-value2 && alpha > 0.001)
//do something
threw an exception that alpha is being used without being initiated.
I thought the expression left of the && would always initiate the value of alpha first, but it seems I may be wrong
Any idea?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
这被解析为:
... 因为
&&
具有比=
更高的“解析优先级”——这可能不是您想要的。尝试:This gets parsed as:
... because
&&
has a higher "parsing precedence" than=
-- which is probably not what you want. Try:这里的底线是,您试图表达的内容不可能通过嵌入了
alpha
声明的单个逻辑条件来表达(尽管其他一些答案声称如此)。其他答案已经向您解释了您的条件并未按照您认为的解析方式进行解析,尽管许多答案在引用条件中
=
运算符的优先级时犯了明显的错误,而实际上那里没有任何=
运算符。正确的解释是,当您在if
条件中声明变量时,语法是带有初始值设定项的声明的语法,因此整个事物的解析方式与解析方式相同,即它是一个使用
value1 - value2 && 初始化的
int alpha
声明阿尔法> 0.001 。其中没有运算符=
。我希望现在您可以明白为什么编译器说您正在初始化表达式中读取未初始化的变量。 编译器也会对以下声明提出同样的抱怨出于同样的原因,
。为了实现您想要表达的内容,您必须预先声明
alpha
或将您的
if
分成两个但是,由于第二个条件已经要求
alpha
大于0
,即使验证第一个也没有多大意义,所以最有意义的事情就是减少当然,正如其他人已经指出的那样,将
int
值与0.001
进行比较是有效的,但相当奇怪。只要做The bottom line here is that what you are trying to express cannot be possibly expressed by a single logical condition with the declaration of
alpha
being embedded into it (despite what some other answers claim).The other answers already explained to you that your condition is not parsed the way you think it is parsed, although many answers make an obvious error of referring to the precedence of
=
operator in the condition, while in reality there's no=
operator there whatsoever. The correct explanation is that when you declare a variable in theif
condition, the syntax is that of declaration with an initializer, so the whole thing is parsed the same way aswould be parsed, i.e. it is a declaration of
int alpha
initialized withvalue1 - value2 && alpha > 0.001
. There's no operator=
in it. And I hope now you can see why the compiler says that you are reading an uninitialized variable in the initializer expression. The compiler would make the same complaint on the following declarationfor the very same reason.
To achieve what you are literally trying to express, you have to either pre-declare
alpha
or split your
if
into twoHowever, since the second condition already requires
alpha
to be greater than0
, it doesn't make much sense to even verify the first one, so the most meaningful thing to do would be to just reduce the whole thing toOf course, as others already noted, the comparison of an
int
value to0.001
is a valid, but rather weird thing to do. Just do始终首先评估左侧。这里的问题是运算符优先级。看看这样是否效果更好:
The left side is always evaluated first. The problem here is operator precedence. See if this doesn't work better:
在澄清其工作原理(出于教育目的)后,不要这样做。不要在同一语句中混合变量初始化/赋值和比较。
如果每个语句单独是一个“命令”或一个“查询”,那就更好了。
如果“if”中的条件非常清晰易读并且明确是布尔值,那就好多了。不是整数,什么也没有,只是布尔值。
条件的第一部分是一个整数。然后你用 bool 来执行 and 操作。您完全没有必要强制进行转换。 准确地给出 if 和条件运算符的要求:布尔值。
After clarifying how it works (for educative purposes), do not do this. Do not mix variable initialization/assignment and comparisons in the same statement.
It is better if each statement is either a "command" or a "query" alone.
And it is much, much better if a condition inside an "if" is very clearly readable, and unequivocally bool. Not integer, no nothing, just bool.
The first part of your condition is an integer. Then you do an and with a bool. You are forcing a conversion with no need at all. Give if's and conditional operators exactly what they ask for: bools.
回答标题中的问题,取决于操作数的类型。
对于内置类型,
&&
短路,意味着计算 LHS,如果为 false,则根本不计算 RHS。对于重载
operator&&
的用户定义类型,它不会短路。以未指定的顺序对双方进行评估,然后调用该函数。不过,我认为其他人已经解决了您需要回答的问题。
Answering the question in the title, it depends on the types of the operands.
For builtin-types,
&&
short-circuits, meaning that the LHS is evaluated, and if it is false then the RHS is not evaluated at all.For user-defined types which have overloaded
operator&&
, it does not short-circuit. Both sides are evaluated, in unspecified order, and then the function is called.I think others have handled the question you need answered, though.
如果我没记错的话,该操作是未定义的。分配给 to 变量,然后在单个语句中引用同一变量是未定义的。
If I'm not mistaken, that operation is undefined. Asigning to to variable and then referring to that same variable in a single statement is undefined.
我通常总是使用括号只是为了让我的代码更清楚地表达我的意图。
I generally always use parenthesis just to make my code a little more clear of my intent.
它是从左到右评估的。
然而,在您的情况下,赋值是最后发生的事情,并且整个事情的行为如下(其中 alpha 用作计算的一部分以获取结果来初始化它):
您不能将变量声明混合到复杂的表达式中,因此以下内容将无法编译:
因此您需要将其分成两行:
It's evaluated from left to right.
In your case, however the assignment is the last thing to happen and they whole thing would behave as (where alpha is used as part of the calculation to get the result to initialize it):
You can't mix variable declarations into complex expressions, therefore the following won't compile:
Therefore you'll need to split it up to two lines:
根据规则将按
步骤3中的顺序进行评估,首先评估 alpha。由于它还没有被分配——也许还没有声明,规则对此并不清楚——它会产生一个错误。
缺陷是赋值的优先级低于
&&
。仍然不起作用,但更接近:Gcc 给出错误:'int' 之前的预期表达式。好吧,也许还没有更近。在最初的声明中,gcc 也说了同样的话。
According to the rules would be evaluated in order as
In step 3, alpha is first evaluated. Since it hasn't been assigned—and maybe not declared, the rules aren't clear on this—it produces an error.
The flaw is that assignment is lower precedence than
&&
. What still doesn't work, but is closer:Gcc gives
error: expected expression before ‘int’
. Well maybe it's not closer. With the original statement, gcc says the same thing.我的猜测是,这是因为您在“if”语句中声明了存储。我什至认为这不会编译。
试试这个。
但我不认为这符合您的需要。您将 alpha 作为 int 类型,然后将其与浮点值进行比较。 && 的第一部分只要 alpha 不为零,语句就会返回 true,如果 alpha 大于 0,第二部分将返回 true。因此,您可能应该这样做
或获得更具可读性的代码,
但要回答您原来的问题: &&从左到右执行并在答案明显时短路。即,如果 && 的第一部分是是假的,第二个甚至没有被评估!
My guess is that it's because you're declaring the storage inside the "if" statement. I didn't even think that would compile.
Try this.
But I don't think this is doing what you need. You have alpha as an int, and you're then comparing it to a floating point value. The first part of the && statement will retrun true as long as alpha is not zero and the second part will return true if alpha is greater than 0. So you should probably do this
or for much more readable code
But to answer your original question: && is executed left to right and short circuited when the answer is obvious. I.e., if the first part of the && is false, the second isn't even evaulated!
这是一篇文章列出运算符优先级和关联性。
据我所知,您的意图是声明一个临时变量,为其分配 value1-value2 的值,然后测试结果,如果大于某个值则进入 if 块。 alpha 被声明为 int,但您似乎将其与 double 进行比较。 alpha 应该是双精度的。
您在使用临时工具方面很有创意。清晰往往比可爱更好。改为这样做:
Here's an article listing operator precedence and associativity.
From what I can tell, your intent is to declare a temporary, assign it the value of value1-value2, then test the result and enter the if block if it is greater than some value.
alpha
is being declares as an int, but you seem to be comparing it against a double. alpha should be a double.Your'e being creative with the use of temporaries. Clear is often better than cute. Do this instead:
根据 :
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
给出你的例子
According to :
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
given your example
正如所写,此表达式执行以下操作:
value1 - value2
并通过与零进行隐式比较将其转换为bool
- 即,它实际上是(value1 - value2 ) != 0
alpha >将
。 此时0.001
截断为int(0)
后为 0.001alpha
尚未初始化。我认为这总结了帖子的其余部分。我发布单独答案的唯一原因是我找不到一个提到当
alpha
未初始化时以及此处发生的所有转换的答案; wallyk 的回答最接近。当然,建议您使用括号和单独声明 alpha 的其余答案正是您应该解决此问题的方法。在 if 语句中声明变量是语言的一部分,我还没有找到很好的用途 - 在重复结构中声明似乎更合适。
As written this expression does the following:
value1 - value2
and converts it to abool
by implicit comparison against zero - i.e., it is effectively(value1 - value2) != 0
alpha > 0.001
after truncating0.001
toint(0)
. At this pointalpha
is not initialized.I think that this summarizes the rest of the posts. The only reason that I posted a separate answer is that I could not find one that mentioned both when
alpha
was not initialized and all of the conversions that are occurring here; wallyk's answer is closest.Of course, the rest of the answers that suggest that you use parentheses and a separate declaration of
alpha
are exactly what you should do to fix this. Declaring variables within anif
statement is part of the language that I haven't found a good use for - declarations within repetition structures seems more appropriate.问题在于该语句的计算方式如下:
if (int alpha = (value1-value2 && alpha > 0.001))
使用括号来修复&&运算符:
if ((int alpha = value1-value2) && (alpha > 0.001))
The problem is that the statement is evaluating like this:
if (int alpha = (value1-value2 && alpha > 0.001))
Use parentheses to fix the left- and right-hand sides of the && operator:
if ((int alpha = value1-value2) && (alpha > 0.001))