我是C#新手,通过编写一个经典的100扇门问题的解决方案来练习。下面的代码(可能是糟糕的)解决了这个问题:
internal class Program
{
private static void Main(string[] args)
{
var doors = new bool[100];
var ints = new int[100];
ints = Enumerable.Range(1, 100).ToArray();
for (int i = 1; i <= 100; i++)
{
ints.Where(j => j % i == 0)
.Select(j => j)
.ToList()
.ForEach(j => doors[j - 1] = !doors[j - 1]); //This is the relevant line.
}
Array.ForEach(doors, i => Console.WriteLine(i));
}
}
我把注解放在上面的行让我很惊讶。它工作得非常好,但是用下面的任何一个替换它都会抛出System.IndexOutOfRangeException
.ForEach(j => doors[--j] = !doors[--j]);
.ForEach(j => doors[j--] = !doors[j--]);
尽管j - 1
是完全正确的,为什么这两个都是无效的呢?我的理解是,在所有情况下,--j
和j--
中只有一个等价于j - 1
。
1条答案
按热度按时间lb3vh1jj1#
我的理解是,在任何情况下,j和j中,只有一个等价于j - 1.
不,绝对不是。
这两个函数失败的原因不同-一个是当
j
初始为1时,另一个是当j
初始为100时。首先考虑一下:
这将
j
* 递减两次 *,并且在每种情况下,都使用递减发生后的j
* 的值。首先计算左手操作数,因此当
j
为1时,数组索引的计算结果为:显然,
doors[-1]
是无效的。现在让我们考虑第二种选择:
这再次将
j
递减两次,但在每次数组索引操作中使用递减前的j
的值。因此,当j
为100时,它将数组索引计算为:这次是
doors[100]
,这是无效的。在您的 working 代码中,您将
j - 1
用于两个索引,而根本不修改j
,因此当j
从1到100时,您使用的数组索引从0到99,这是有效的。我强烈建议不要在任何表达式或语句中使用前/后增量/减量,因为您在多个位置使用了修改后的变量-并且 * 绝对 * 避免在同一表达式或语句中多次使用同一变量的前/后增量/减量。