1

我在代码中发现了一个错误(if 语句应该有“==”而不是“=”),我有几个问题。

示例代码:

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

据我所知,它应该总是调用 A()。
1.我的假设是否正确()?
2.所有/大多数编译器都是这种情况(任何例外)?

4

6 回答 6

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

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

if( 12 == x )

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

于 2012-07-06T09:28:35.403 回答
6

如果MyFunction()返回零 ( 0) 它将调用 B(); 否则它将调用 A()。赋值表达式的值是赋值给左侧的值;在if语句中,0 被视为假,所有其他值都被视为真。

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

如果您打算分配i并测试返回值,您应该编写if ((i = MyFunction()));额外的括号向编译器(和读者)发出赋值的信号。

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

于 2012-07-06T09:28:31.740 回答
4

该语句是一个赋值:

i = MyFunction()

if 语句实际上是在检查 i 的值。如果 MyFunction() 返回 0,则 i 被赋值为 0,它等效于:

if(0)

这评估为假,在这种情况下不会调用 A()

于 2012-07-06T09:28:44.797 回答
3

A如果函数返回非零,它将采用真正的分支(即 call )。零被视为假,因此如果MyFunction()返回零,它将B改为调用。

实际上,是的,这对于大多数/所有编译器都是正确的。我认为 0=false 只是一个约定;如果它现在在 C99 或更高版本中正式化,我不会感到惊讶,但我没有手边的副本可以让您参考正确的部分。

于 2012-07-06T09:27:39.600 回答
3

你的假设是不正确的。

-condition 中的表达式if与任何其他表达式一样被评估,在您的情况下,结果(i = MyFunction())是 的返回值MyFunction()

于 2012-07-06T09:28:53.170 回答
2

您的代码将评估

  (i = MyFunction())

如果MyFunction()返回非零值,则表达式将被评估为 true 并调用A()。除此以外B()

于 2012-07-06T09:30:10.227 回答