Din*_*ina 19 language-agnostic while-loop
while循环中的off-by-one错误究竟是什么?我如何解决它以及如何解决它?谢谢
Mar*_*ers 40
一个差一错误是,例如当你写打算执行循环n次,写类似:
for (int i = 1; i < n; ++i) { ... }
Run Code Online (Sandbox Code Playgroud)
要么:
for (int i = 0; i <= n; ++i) { ... }
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,循环将执行(n - 1)次,在第二种情况下(n + 1)次,将名称逐个给出.其他变化是可能的,但是通常由于循环变量的初始值或循环的结束条件中的错误,循环执行太多次或太少次.
循环可以正确编写为:
for (int i = 0; i < n; ++i) { ... }
Run Code Online (Sandbox Code Playgroud)
for循环只是while循环的一个特例.在while循环中可以产生同样的错误.
相差一错误是指您期望某个值的值为 N,但实际上它最终为 N-1 或 N+1。例如,您期望程序执行某项操作 10 次,但最终执行了 9 或 11 次(一次太少或一次太多)。在编程中,这种情况在处理“for”循环时最常见。
发生此错误是由于误判,您没有意识到用于跟踪计数的数字可能与您正在计数的物品数量不同。换句话说,您用来计数的数字可能与您正在计数的事物总数不同。没有任何东西要求两件事必须相同。试着大声从 0 数到 10,最终你总共说出了 11 个数字,但你最后说出的数字是 10。
防止这个问题的一种方法是认识到我们的大脑有犯错误的倾向(可能是认知偏差)。牢记这一点可能会帮助您识别并预防未来的情况。但我想防止这个错误最好的办法就是编写单元测试。这些测试将帮助您确保您的代码正常运行。
假设您有以下带有数组和for
循环的代码:
char exampleArray[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };
for(int i = 0; i <= 11; i++)
{
print(exampleArray[i])
}
Run Code Online (Sandbox Code Playgroud)
看到这里的问题了吗?因为我计算出数组中有 11 个字符,所以我将循环设置为迭代 11 次。然而,在大多数语言中,数组从零开始,这意味着当我的代码打印时
exampleArray[11]
Run Code Online (Sandbox Code Playgroud)
我将收到索引越界错误,因为示例中的数组在索引 11 处没有值。
在这种情况下,我可以通过简单地告诉循环少迭代一次来轻松解决此问题。
调试此问题的最简单方法是打印出上限和下限,并查看哪个值会生成索引越界错误,然后将您的值设置为比整个迭代中的值大一或小一。
当然,这假设错误是由循环超出或小于数组边界而生成的,还有其他情况可能会发生索引越界错误,但是,这是最常见的情况。索引越界总是指尝试访问由于过去的边界不在数据边界内而数据不存在的数据。