【问题标题】:Index was outside of the bounds of the array [duplicate]索引超出了数组的范围[重复]
【发布时间】:2011-04-11 17:37:00
【问题描述】:

未处理的异常: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++;
            }
    }

我唯一能想到的是我的程序正在检查

【问题讨论】:

  • 请添加 parentGen 的声明以确保答案最有帮助。
  • int[,] parentGen = new int[arrayRows, arrayCols];

标签: c# indexoutofrangeexception


【解决方案1】:

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

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

编辑:示例代码

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

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

【讨论】:

  • 将 x 设置为 1 可以解决问题,但我知道这不是好的编码习惯?
  • 这不是不好的做法,是不好的逻辑。如果你这样做,你不会检查所有你想要的条件。
  • 将 x 设置为 1 只会阻止抛出异常,实际上并不能解决问题,因为现在您没有检查单元格 (0, 0) 的邻居,您真正需要做的是不检查某些不存在的相邻部分,例如 x = 0 列左侧的单元格和 y = 20 行下方的单元格。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    你的数组从 0->21 开始。同样,您正在测试 [-1, -1] 和 [22, 22] 的值,您可以通过将 for 语句链接到

    来修复它
    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

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

    3. 您的集合未初始化

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

    【讨论】:

      【解决方案4】:

      问题是您正在查看前一个值和下一个值(-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 的直接访问权限替换为对函数的调用即可。

      【讨论】:

        【解决方案5】:

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

        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();
        
        }
        

        【讨论】:

          猜你喜欢
          • 2012-01-31
          • 1970-01-01
          • 2014-04-11
          • 1970-01-01
          • 1970-01-01
          • 2016-05-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多