if语句中带有等号"="而不是"=="的语句

Bo.*_*Bo. 0 c

我在代码中发现了一个错误(if语句应该有"=="instad"=")并且我几乎没有问题.

示例代码:

int i = 5;
if (i = MyFunction())  // MyFunction() returns an int; this is where bug was made
{
  // call A()
}
else
{
  // call B()
}
Run Code Online (Sandbox Code Playgroud)

从我收集它应该总是调用A().
1.我的假设是否正确()?
2.这种情况适用于所有/大多数编译器(任何例外)吗?

unw*_*ind 7

  1. 不,只有A()在赋值被认为是真的时才会调用,即非零.
  2. 是的,这是标准的.编写代码不是一个很好的方法,因为混淆的风险很大.

有些人翻转比较,将常量写到左边,以避免风险:

if( 12 == x )
Run Code Online (Sandbox Code Playgroud)

但是当然这对你的情况不起作用,因为它确实是一项任务.大多数编译器会在检测到此代码时向您发出警告,因为它通常是导致错误的原因.

  • 那些翻转的条件被称为"尤达条件"("如果12是计数,则执行此操作").见http://www.dodgycoder.net/2011/11/yoda-conditions-pokemon-exception.html (2认同)
  • 此外,自1990年Borland发布了一个编译器,为"可能不正确的分配"发出警告时,yoda废话已经过时了.从那以后,每一个体面的编译器都有这个警告.所以不要混淆你的代码,确保你得到编译器警告. (2认同)

eca*_*mur 5

如果MyFunction()返回零(0),它将调用B(); 否则会调用A().赋值表达式的值是分配给左侧的值; 在if语句0中被视为false而所有其他值被视为true.

这是完全合法的代码,尽管许多编译器会发出警告.它有效的原因是在C和类似语言中,赋值是一个表达式(而不是语句).

如果您打算分配i并测试您应该写的返回值if ((i = MyFunction())); 额外的括号向编译器(以及读者)发出指示.

如果相反,你打算测试i你应该写的价值if (MyFunction() == i); 通过将函数调用放在左侧,您可以确保如果错过了双等号,代码将无法编译(MyFunction() = i通常不是有效的表达式).