我是 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.
uj5u.com熱心網友回復:
據我了解,在所有情況下,--j 和 j-- 中的一個將等同于 j - 1。
不,絕對不是。
但是,這兩個失敗的原因不同——一個j最初是 1,另一個j最初是 100。
首先考慮這個:
.ForEach(j => doors[--j] = !doors[--j]);
遞減j 兩次,并且在每種情況下都使用遞減發生j 后的值。
左邊的運算元首先被評估,所以當j是 1 時,這最終評估陣列索引為:
doors[0] = !doors[-1];
顯然,doors[-1]是無效的。
現在讓我們考慮第二種選擇:
.ForEach(j => doors[j--] = !doors[j--]);
這再次遞減j兩次,但在每個陣列索引操作中使用遞減j 之前的值。所以當j是 100 時,這最終評估陣列索引為:
doors[100] = !doors[99];
這次doors[100]是無效的。
在您的作業代碼中,您正在使用j - 1兩個索引,j根本沒有修改,因此j從 1 到 100,您使用的陣列索引從 0 到 99,這是有效的。
我強烈建議不要在任何運算式或陳述句中使用前/后遞增/遞減,如果您在多個地方使用修改后的變數 - 并且絕對避免在同一運算式中多次對同一變數進行前/后遞增/遞減或宣告。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/536497.html
標籤:C#林克增量索引越界异常
