索引超出了数组的范围

时间:2010-09-13 15:18:35

标签: c# indexoutofrangeexception

未处理的异常:System.IndexOutOfRangeException:索引超出了数组的边界(在第一个if语句处)

    static int arrayRows = 20;
    static int arrayCols = 20;

    public void printBoard()
    {
        int neighbours;
        for (y = 0; y < arrayCols; y++)
            for (x = 0; x < arrayRows; x++)
            {
                neighbours = 0;
                // Count number of neighbours surrounding live cell
                if (parentGen[x-1, y-1] == 1) // top left 
                    neighbours++;
                if (parentGen[x-1, y] == 1)  // left
                    neighbours++;
                if (parentGen[x-1, y+1] == 1) // bottom left
                    neighbours++;
                if (parentGen[x, y-1] == 1)  // middle top
                    neighbours++;
                if (parentGen[x, y+1] == 1)  // middle bottom
                    neighbours++;
                if (parentGen[x+1, y-1] == 1) // top right
                    neighbours++;
                if (parentGen[x+1, y] == 1)  // right
                    neighbours++;
                if (parentGen[x+1, y+1] == 1) // bottom right
                    neighbours++;
            }
    }

我唯一能想到的是我的程序正在检查&lt;的坐标。 0?我该如何解决这个问题?

5 个答案:

答案 0 :(得分:9)

你的第一个坐标是parentGen [-1,-1],这将始终抛出异常。

您需要检查您所在的单元格是否在左侧,右侧,顶部或底部有任何邻居。例如,x = 0左边没有邻居,y = 20左边没有邻居。您可能希望将其分解为其他函数,例如HasNeighborsLeft(int x)等。

编辑:示例代码

if(x > 0 && y > 0 && parentGen[x - 1, y - 1] == 1)
{
    neighbors++;
}

你可以将它分解为它自己的函数,并且你可以围绕所有涉及x - 1的检查包装这种逻辑。

答案 1 :(得分:1)

您需要在其范围的顶部和底部对x和y进行边界条件检查。您无法使用+1和-1偏移合法地索引整个阵列。将检查分解为x == 0x == arrayRows-1的边界条件情况(此处不检查无效的相对偏移),然后检查x+1x-1始终有效的情况在else中。与y相似。

答案 2 :(得分:0)

你的阵列从0-> 21开始。同样,你正在测试[-1,-1]和[22,22]的值你可以通过将你的陈述加到

来修复它。
for (int x = 1; x <= arrayCols - 1; x++)
    for (int y = 1; y <= arrayRows - 1; y++)

此外,循环问题几乎总是由您可以随时检查的少数情况引起:

  1. 您的for语句a)从数组的下限开始,或b)以更高的数字结束 a)for(int x = -1; b)for(int x = 0; x&lt; = array.Length

  2. 循环中的代码访问索引器范围之外的值 for(int x = 0 ...     array [x-1,...

  3. 您的收藏未初始化

  4. 在这种情况下,你的问题2。

答案 3 :(得分:0)

问题是你正在查看上一个和下一个值(-1和+1),它们显然会超出数组两端的数组范围。

有几种方法可以解决这个问题:

  • 创建一个更大的数组,边缘周围有一个虚拟的“边框”,你不会用于你的电路板,但允许你使用与你现在的代码非常相似的代码(你的-1和+1前一个和下一个细胞逻辑)。 (想象一下10x10的国际象棋棋盘,你不允许在最外面的方块中进行比赛)。
  • 分散加载'if'语句以检查您是否在数组中的第一个或最后一个项目,从而避免进行任何无效的数组访问。
  • 创建一个函数来检索特定单元格中的项目,并在此函数中放置条件逻辑以处理数组边界。

我个人会选择最后一个选项,自己构建一个获取指定单元格状态的函数,检查索引是否有效,如果不是则返回默认值。例如:

private const int EMPTY_CELL = 0;
private const int INVALID_CELL = EMPTY_CELL; // for now the same, but gives scope to handle separately

private int GetCellState(int row, int column)
{
    if (row < 0) return INVALID_CELL;
    if (column < 0) return INVALID_CELL;
    if (row >= arrayRows) return INVALID_CELL;
    if (column >= arrayColumns) return INVALID_CELL;

    return parentGen[row, column];
}

这只是通过调用函数来交换对parentGen的直接访问的问题。

答案 4 :(得分:0)

你可以先创建一个只有有效索引的序列,然后迭代它们的组合:

static int arrayRows = 20;
static int arrayCols = 20;

public void printBoard()
{
    var sequences = from row in Enumerable.Range(0, arrayRows)
                    from column in Enumerable.Range(0, arrayCols)
                    select new
                    {
                        Rows = (from xs in new[] { row - 1, row, row + 1 }
                                where xs >= 0 && xs < 20
                                select xs),
                        Columns = (from ys in new[] { column - 1, column, column + 1 }
                                   where ys >= 0 && ys < 20
                                   select ys)
                    };
    //now that we have a sequence with all the needed (valid) indices 
    //iterate through the combinations of those
    var neighbours = (from seq in sequences
                      from row in seq.Rows
                      from column in seq.Columns
                      where row != column && parentGen[row, column] == 1
                      select 1).Count();

}
相关问题