&&&运算符的交换性质问题



我一直在遇到的奇怪问题的代码是为了修剪整数数组的未使用部分,然后将其转换为字符串。

ex: _ABC__DE______将成为_ABC__DE

当输入填充默认字符时,出现的问题。(示例中的" _")。

sLength是整数阵列chars

的长度

有问题的代码:

  int inputLength = sLength - 1;
  while (chars[inputLength] == defaultChar && inputLength >= 0) {
    inputLength--;
  }
  inputLength++;
  Serial.println("input length: " + String(inputLength));
  // (in)sanity check
  Serial.println(inputLength);
  Serial.println(String(inputLength));
  Serial.println(inputLength <= 0);
  Serial.println(0 <= 0);
  Serial.println(inputLength == 0);
  Serial.println(0 == 0);
  if (inputLength <= 0) {
    //reset cursor position
    Serial.println("index set to 0");
    index = 0;
  } else {
    output = "";
    for (int i = 0; i < inputLength; i++) {
      char c = charSet[chars[i]];
      if (c == '_') {
        c = ' ';
      }
      output += c;
    }
    done = true;
  }

给出填充defaultChar的数组时的输出:

input length: 0
0
0
0
1
0
1

如果我要正确解释,则输出意味着偶数线上的0> 0 =/= 0,但是0&lt; = 0和0 = 0 = 0 = 0。


我想出的解决方法是替换

  while (chars[inputLength] == defaultChar && inputLength >= 0) {
    inputLength--;
  }

使用以下

之一
  while (inputLength >= 0 && chars[inputLength] == defaultChar) {
    inputLength--;
  }

  while (chars[inputLength] == defaultChar) {
    inputLength--;
    if (inputLength < 0) {
      break;
    }
  }

两者都导致输出:

input length: 0
0
0
1
1
1
1
index set to 0

为什么这会改变结果?据我所知,直到现在,操作员是可交值的。

我缺少有东西

chars[inputLength] == defaultChar && inputLength >= 0

不等于

inputLength >= 0 && chars[inputLength] == defaultChar

如果是相关的,则使用IDE 1.8.8

在328p arduino nano上运行。

&&不交换。它首先评估左操作数,然后停止如果左操作数评估为0

您的原始代码失败,因为在某个时候它会评估chars[-1](如果chars是数组,则会导致不确定的行为)。替代版本没有这个问题,因为它在使用inputLength作为数组索引之前执行>= 0测试。

&&是合理的,因为a && b的结果与b && a的结果相同。但是内置的操作员&&具有短路行为。这意味着,如果a && b的结果可以通过单独评估第一操作数来决定,则未评估第二个操作数。

因此,当第一个操作数为 chars[inputLength] == defaultCharinputLength-1时,您进入了不确定行为的领域,这意味着程序的行为是不可预测的。但是有了解决方法,您避免由于inputLength >= 0inputLength < 0检查而避免使用不确定的行为,因此代码按预期工作。

正如@petebecker注意:如果a()b()具有副作用,则a() && b()不合理。

最新更新