使用赋值作为条件表达式?
Posted
技术标签:
【中文标题】使用赋值作为条件表达式?【英文标题】:Using assignment as a condition expression? 【发布时间】:2011-10-12 01:15:12 【问题描述】:考虑:
if (a=5)
/* do something */
作业如何作为条件起作用?
是不是基于l-value的非零值?
【问题讨论】:
你是用 C++ 还是 C 编译?int war = false; if(war = true) launchnuke();
@WTP:永远不要将布尔值与任何东西进行比较。布尔值已经是布尔值:if (war) launchnuke();
将true
或false
分配给非布尔值的程序员应该受到各种针对他们的攻击。
@David:WTP 在哪里比较布尔值和布尔值?
@Tomalak:他没有,但if(var = true)
可能打算成为if(var == true)
。首先将其写为if (var)
可以巧妙地避免潜在的=
与==
的混淆。
【参考方案1】:
在更现代的用法中,您有时可能会看到这种模式用于处理 optional
s:
std::optional x = ...;
if (auto v = x)
// Block only executes if x contained a value, accessible as *v
【讨论】:
【参考方案2】:C++ — ISO/IEC 14882:2003(E)
[5.17/1]
有几个赋值操作符,都是分组的 右到左。都需要一个可修改的左值作为左操作数, 赋值表达式的类型是其左操作数的类型。 赋值操作的结果是左边存储的值 赋值后的操作数;结果是一个左值。
表达式a = 5
的结果是5
。
[6.4/4]
[..] 作为表达式的 condition 的值是 表达式,隐式转换为bool
switch
。 [..]
发生到bool
的转换。
[4.12/1]
算术、枚举、指针或指向成员的指针的右值 type 可以转换为bool
类型的右值。零值,null 指针值,或者空成员指针值转换为false
; 任何 其他值转换为true
。
5
转换为布尔值true
。
[6.4.1/1]
如果条件 (6.4) 第一个结果为真 子语句被执行。 [..]
true
被视为if
语句成功。
C — ISO/IEC 9899:1999(E)
[6.5.16/3]
赋值运算符将值存储在对象中 由左操作数指定。 赋值表达式具有值 赋值后的左操作数,但不是左值。 [..]
表达式a = 5
的结果是5
。
[6.8.4.1/2]
在这两种形式中,如果 表达式比较不等于 0。 [..]
5
被视为if
语句成功。
一般
这样的代码几乎总是错误的;作者可能打算if (a == 5)
。然而,有时它是故意的。你可能会看到这样的代码:
if (x = foo())
cout << "I set x to the result of foo(), which is truthy";
// ... stuff
【讨论】:
为了确保没有错,你可以写if ((a=5) != 0)
,它在语义上与if (a=5)
相同。
0.0
会被视为零值吗?
@Stan:在我看来为零! (虽然记得浮点是不准确的。)
由于该问题同时被标记为 C 和 C++,因此可能很高兴提及您引用的是 C++,而不是 C。两者的推理相当不同。
@Tomalak Geret'kal:字体可以小一点。【参考方案3】:
是的,它基于分配给 a 的零/非零值。对于某些人(包括我自己)来说,在代码中使用带有副作用的表达式也被认为是不好的做法,因此上述代码片段最好写成类似
a = 5;
...
if (a != 0)
...
【讨论】:
我认为 if (int a=foo()) ... ... if-scoped assignment 没问题。【参考方案4】:if(a=x)
等价于 if(x)
除了分配有x
的a
。因此,如果表达式x
的计算结果为非零值,那么if(x)
将简单地变为if(true)
。否则变为if(false)
。
在您的情况下,由于x = 5
,这意味着f(a=5)
除了分配有5
的a
之外,还等同于if(true)
。
【讨论】:
这有点误导:if(a=5)
不等同于if(true)
,因为它也分配了a
。
-1: if (a = x)' and
if (x)' 不等价,第一个表达式有副作用。
@interjay:我刚刚编辑了这个,当时你们俩都在评论。【参考方案5】:
每个非零值都将被视为true。
所以有些人会建议你写
5 == a
为了避免你犯==的错误=。
【讨论】:
现在大多数编译器都会警告这个错误。 @Bo Persson:当然是这样。但是有些懒惰的人想关闭警告,所以让我们将其设为错误而不是警告。 -1:对我来说这是丑陋的,并没有提供通用的解决方案。 我不建议写5 == a
。我建议写a == 5
。 :) 去做就对了;这并不难。如果你关闭警告,那么你应该得到你所得到的一切。
@Tomalak Geret'kal:我同意你的看法。所以我说的是“一些人”,而不仅仅是“我”。当然 '5==a' 很丑陋,但是,有些人(例如我的老板)会协助...有时您必须投降。以上是关于使用赋值作为条件表达式?的主要内容,如果未能解决你的问题,请参考以下文章