我一直在遇到的奇怪问题的代码是为了修剪整数数组的未使用部分,然后将其转换为字符串。
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
&&
不交换。它首先评估左操作数,然后停止如果左操作数评估为0
。
您的原始代码失败,因为在某个时候它会评估chars[-1]
(如果chars
是数组,则会导致不确定的行为)。替代版本没有这个问题,因为它在使用inputLength
作为数组索引之前执行>= 0
测试。
&&
是合理的,因为a && b
的结果与b && a
的结果相同。但是内置的操作员&&
具有短路行为。这意味着,如果a && b
的结果可以通过单独评估第一操作数来决定,则未评估第二个操作数。
因此,当第一个操作数为 chars[inputLength] == defaultChar
和 inputLength
是 -1
时,您进入了不确定行为的领域,这意味着程序的行为是不可预测的。但是有了解决方法,您避免由于inputLength >= 0
和inputLength < 0
检查而避免使用不确定的行为,因此代码按预期工作。
正如@petebecker注意:如果a()
或b()
具有副作用,则a() && b()
不合理。