为什么我的条件检查不能互换?

huangapple go评论66阅读模式
英文:

Why aren't my conditional checks interchangeable?

问题

以下是您提供的代码的中文翻译部分:

好的,所以我要从显示我的while和if-check循环的工作版本开始:

int letterIndex = 0;
int rows = sizeof letterArr / sizeof letterArr[0];

while(letterIndex < rows) {
  if(letter == letterArr[letterIndex][0]) {
    break;
  } else {
    letterIndex++;
  }
}

...然后当循环的条件不再为真时,我显然会执行一些操作。很酷。

但是一开始我尝试使用这个条件来退出循环:

int letterIndex = 0;
int rows = sizeof letterArr / sizeof letterArr[0];

while( (letter != letterArr[letterIndex][0]) && (letterIndex < rows) ) {
  letterIndex++;
}

...然后我最终陷入了一个永不结束的循环。第二个条件 letterIndex < rows 永远不会评估为 false

然后当我尝试这个下一个配置时:

int letterIndex = 0;
int rows = sizeof letterArr / sizeof letterArr[0];

while(letter != letterArr[letterIndex][0]) {
  if(letterIndex < rows) {
    break;
  } else {
    letterIndex++;
  }
}

...我对发生的情况感到非常困惑。出于某种原因,我交换了条件语句,以便 letterIndex < rows 打破了while循环,但对我来说这只会让事情更加混乱。在这个上下文中,letterIndex < rowsletter == letterToArr[letterIndex][0] 不应该是可以互换的吗?

我打印出了大量关于变量值的调试消息,从输出的语句中,这段代码的另外两个版本应该像我所预期的那样工作:当 letterIndex 大于 rows 的值时,该语句评估为 false

我不确定这是否非常有帮助,但我正在使用Arduino Uno板,并且我更多地是一个Web开发人员。我尝试过C++,但从未在其中做过专业工作,因此无疑这是因为我对Arduino架构或C++的理解/知识不足造成的。可能两者都有影响。

英文:

Okay, so I'm going to start with showing the working version of my while and if-check loop:

  int letterIndex = 0;
  int rows = sizeof letterArr / sizeof letterArr[0];

  while(letterIndex &lt; rows) {
    if(letter == letterArr[letterIndex][0]) {
      break;
    } else {
      letterIndex++;
    }
  }

...and then I obviously do some stuff when the loop's condition is no longer true. Cool.

But at first I was trying to break the loop with this condition:

  int letterIndex = 0;
  int rows = sizeof letterArr / sizeof letterArr[0];

  while( (letter != letterArr[letterIndex][0]) &amp;&amp; (letterIndex &lt; rows) ) {
    letterIndex++;
  }

...and I'd just end up in a never ending loop. The second condition letterIndex &lt; rows never changed its evaluation to false.

And then when I tried this next configuraiton:

  int letterIndex = 0;
  int rows = sizeof letterArr / sizeof letterArr[0];

  while(letter != letterArr[letterIndex][0]) {
    if(letterIndex &lt; rows) {
      break;
    } else {
      letterIndex++;
    }
  }

...I was super confused with what was going on. For some reason I switched the condition statements so letterIndex &lt; rows broke the while loop but that just makes this more confusing for me. In this context shouldn't letterIndex &lt; rows and letter == letterToArr[letterIndex][0] be interchangeable?

I printed out a ton of debugging messaging around the variable's values and from the outputted statements the other two versions on this code should be working like I'd assume: when the letterIndex is more than the rows value then the statement evaluates to false.

I'm not sure if this is super helpful but I'm working on an Arduino Uno board and I'm more of a web developer. I've dabbled in C++ but I've never done anything professional with it so no doubt this is due to my lack of understanding/knowledge for either the Arduino architecture or C++. Possibly both.

答案1

得分: 2

这段代码

while( (letterIndex < rows) && (letter != letterArr[letterIndex][0]) ) {

具有未定义行为,因为您在使用letterIndex访问letterArr数组之后才检查letterIndex是否小于rows。由于检查是在之后进行的,您最终会在数组上进行超出界限的访问,导致未定义的行为。也就是说,我有点惊讶它导致了一个无限循环。

正确的代码是

while( (letterIndex < rows) && (letter != letterArr[letterIndex][0]) ) {

运算符&&总是从左到右进行评估。如果左侧评估为false,则右侧根本不会被评估。这避免了您版本中出现的数组越界访问。类似的规则也适用于运算符||。这被称为短路求值

英文:

This code

while( (letter != letterArr[letterIndex][0]) &amp;&amp; (letterIndex &lt; rows) ) {

has undefined behaviour because you check if letterIndex is less than rows after you use letterIndex to access the letterArr array. Because the check is afterwards you will end up making an out of bound access on your array and that leads to undefined behaviour. That said I'm a bit surprised it led to an infinite loop.

The correct code is

while( (letterIndex &lt; rows) &amp;&amp; (letter != letterArr[letterIndex][0]) ) {

Operator &amp;&amp; is always evaluated left to right. And if the left hand side evaluates to false, the right hand side is not evaluated at all. This avoids the out of bounds array access that your version had. Similar rules apply to operator ||. This is known as short circuit evaluation.

答案2

得分: 1

你不被允许在letterIndex超出范围时访问letterArr[letterIndex]。在工作版本中,你首先检查条件letterIndex < rows,因此不会出现这种情况。在两个不工作的版本中,你在没有先检查letterIndex是否为有效索引的情况下访问letterArr[letterIndex],导致未定义行为。

英文:

You are not allowed to access letterArr[letterIndex] when letterIndex is out of range. In the working version you don't because you first check the condition letterIndex &lt; rows. In both versions that don't work you access letterArr[letterIndex] without checking first if letterIndex is a valid index resulting in Undefined Behavior.

huangapple
  • 本文由 发表于 2023年4月17日 15:48:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76032804.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定