2012-07-30 153 views
0

以下是我遇到问题的一段代码的极简化版本。可能由if语句导致的C++布尔逻辑错误

int i = 0; 
int count = 0; 
int time = 50; 
int steps = 1000; 
double Tol = 0.1; 
bool crossRes = false; 
bool doNext = true; 

for (int i=0; i<steps; i++) { 

//a lot of operations are done here, I will leave out the details, the only 
//important things are that "dif" is calculated each time and doNext either 
//stays true or is switched to false 

    if (doNext = true) { 
     if (dif <= Tol) count++; 
     if (count >= time) { 
      i = steps+1; 
      crossRes = true; 
     } 
    } 
} 

    if (crossRes = true) { 
     printf("Nothing in this loop should happen if dif is always > Tol 
       because count should never increment in that case, right?"); 
    } 

我的问题是,每次它被用在for循环完成时,它执行里面的“如果(crossRes =真)”括号即使计数没有被增加的语句。

+1

其== == true。 =分配一个值而不是比较它 – 2012-07-30 21:23:55

+0

请不要在您的问题中编辑更正的代码。这使得不可能看到问题是什么,并导致答案没有意义。我要恢复你的编辑。 – 2012-07-30 21:30:04

回答

2

我认错:

if (crossRes) 
你不会有这样的问题,如果你的条件是 如果(真= crossRes) 因为它不会编译。 `crossRes = true`总是评估为`true`,因为它是一个赋值,为`true`。 你想`crossRes == TRUE`: 如果(crossRes ==真){printf的 (“在这个循环中的任何内容都不如果DIF总是因为计数不应该在这种情况下增加,对发生>托尔 ?” ); }
+1

为什么不'if((crossRes == true)== true)'?递归冗余耶! – 2012-07-30 21:26:39

+1

不,你想'if(crossRes)'。和所谓的“Yoda条件”像'if(42 == x)'可以避免==/=问题,但恕我直言,他们是丑陋的。 – 2012-07-30 21:32:58

1

=是赋值,==是等同比较。你想:

if (crossRes == true) { 

您在此处犯同样的错误:

if (doNext = true) { // Bad code 
5

你已经有了一个共同的(并且很令人沮丧)的错误:

if (crossRes = true) { 

此行分配crossRestrue并返回true。您正在寻找比较crossRestrue,这意味着你需要另一个等号:

if (crossRes == true) { 

或者更简洁:

if (crossRes) { 
+0

我想'如果(crossRes){'绝对是最好的使用在这里。 ' == true'非常多余。 – 2012-07-30 21:28:21

1

这里其他的答案告诉你的问题。通常,你的编译器会警告你,但一个方法,以确保你不这样做,这是把常数项左侧

true == crossRes 

这样你得到一个编译错误,而不是警告的,所以它不能逃脱不被注意,因为

true = crossRes 

不会编译。

+0

我总是想知道为什么有些人把常量放在左边......这对我来说很奇怪,但这是一个很好的解释。 – cdhowie 2012-07-30 21:28:51

+1

也被称为“尤达条件” – 2012-07-30 21:29:21

1

首先,尽管许多人指出if (crossRes = true)的问题,但由于某些原因,他们还没有(但仍然)指出与if (doNext = true)相同的问题。

我会坚持指出,你真的想要if (crossRes)而不是if (crossRes == true)(或甚至if (true == crossRes))。

第一个原因是它避免了从简单的拼写错误中遇到同样的问题。

第二个是比较的结果是bool - 所以如果if (crossRes==true)是必要的,您可能需要if (((((crossRes == true) == true) == true) == true)只是为了确定(也许更多 - 你永远不知道)。当然,这当然是非常愚蠢的 - 你从bool开始,所以你不需要比较就可以得到bool

我还会注意记录,如果你坚持要进行比较,你应该几乎总是使用if (x != false)而不是if (x == true)。虽然它并不适用于C++,但在旧C中没有实际的布尔类型,可以使用任何整数类型 - 但在这种情况下,与true的比较可能会给出不正确的结果。至少通常,false将为0,并且true将为1 - 但在测试时,任意将计为等于true。例如:

int x = 10; 

if (x) // taken 

if (x == true) // not taken, but should be. 

如果你在这里你不是一个布尔值开始,接着if (<constant> <comparison> <variable>)是有道理的,是(IMO)首选。但是,无论如何,当你开始使用布尔值时,只需使用它;不要进行比较来产生另一个相同的结果。

+2

如果你坚持要进行比较,你应该*忽略它*。将平等或不平等的数值与“真”或“假”比较是不必要的,并且可能是危险的。只要写'if(x)'或'if(!x)'即可。看[这个问题](http://programmers.stackexchange.com/q/136908/33478)和[我的回答](http://programmers.stackexchange.com/a/136933/33478)。 – 2012-07-30 21:35:54