【问题标题】:Index was outside the bounds of the array? I'm not sure. C#指数数组的边界之外?我不知道。 C#
【发布时间】:2018-06-22 16:05:48
【问题描述】:

我想创建一个方法,它搜索数组中的最大值并用它们创建另一个数组。然后,所有这些值都应该打印在richTextBox 中(因为之后我会将它们与文本绑定,我想将它们与每个值一起打印)。

我的方法的代码:

private void selectPattern() {
    int[] tab = new int[12];
    int max = 0;
    int k = 0;
    int[] j = new int[12];

    for (int l = 0; l < 12; l++) {
        j[l] = 0;
    }

    // Patterns

    tab[0] = 3;
    tab[1] = 2;
    tab[2] = 5;
    tab[3] = 7;
    tab[4] = 1;
    tab[5] = 4;
    tab[6] = 4;
    tab[7] = 11;
    tab[8] = 3;
    tab[9] = 11;
    tab[10] = 11;
    tab[11] = 3;

    // Counting
    for (int i = 0; i < 12; i++) {
        if (tab[i] >= max) {
            max = tab[i];
            j[k] = i;
            k++;
            for (k = 0; k < 12; k++) {
                if (j[k] != 0) {
                    richTextBox1.Text = j[k].ToString();
                    richTextBox1.Text = Environment.NewLine;
                }
            }
        }
    }
}

但它只是第一次工作,现在我得到了:

System.IndexOutOfRangeException:索引超出了数组的范围。 在 Form1.cs:line 59 中的 WindowsFormsApp2.Form1.selectPattern() 处

第 59 行是这样的:

j[k] = i;

我在方法的开头为k 设置了 0 值,所以我假设每次调用此方法时都应该重写该索引。谁能解释一下,为什么它不起作用?

感谢您的帮助

@编辑 变量名称更具描述性的代码

private void selectPattern()
    {
        int[] valueTab = new int[12];
        int maxValue = 0;
        int indexIndex = 0;
        int[] indexTab = new int[12];

        //Filling indexTab with zeroes

        for (int zeroIndex = 0; zeroIndex < 12; zeroIndex++)
        {
            indexTab[zeroIndex] = 0;
        }

        //Patterns

        valueTab[0] = 3;
        valueTab[1] = 2;
        valueTab[2] = 5;
        valueTab[3] = 7;
        valueTab[4] = 1;
        valueTab[5] = 4;
        valueTab[6] = 4;
        valueTab[7] = 11;
        valueTab[8] = 3;
        valueTab[9] = 11;
        valueTab[10] = 11;
        valueTab[11] = 3;

        //Counting
            for (int valueIndex = 0; valueIndex < 12; valueIndex++)
            {
                if (valueTab[valueIndex] >= maxValue)
                {
                    maxValue = valueTab[valueIndex];
                    indexTab[indexIndex] = valueIndex;
                    indexIndex++;
                    for (indexIndex = 0; indexIndex < 12; indexIndex++)
                    {
                        if (indexTab[indexIndex] != 0)
                        {
                            richTextBox1.Text = indexTab[indexIndex].ToString();
                            richTextBox1.Text = Environment.NewLine;
                        }
                        else
                        {
                            richTextBox1.Text = "." + Environment.NewLine;
                        }
                    }
                    indexIndex = 0;
                }

            }

        }

【问题讨论】:

  • 这段代码演示了为变量命名以表明其用途的价值
  • k 的用途是什么?为什么在外循环和内循环的计数器中都使用它?

标签: c# arrays exception indexing


【解决方案1】:

for ( k = 0; ... 循环第一次完成后,k 的值为 12。因此,您尝试分配给 j[k],即超出范围的 j[12]

每次调用方法本身时,k 的值都设置为 0,但在 for ( int i = 0; ... 循环体的开头之后不会设置为 0,因此 12 的值从第一次执行 (i = 0) 到第二次执行 (i = 1)。

你应该给你的变量一个描述性的名字。它将帮助您和其他人更好地理解代码并避免许多问题。经过深思熟虑的努力,我认为您想要的是以下内容:

// find max values
for (int i = 0; i < 12; i++) {
    if ( tab[i] > max ) k = 0; //reset position in target array for new max
    if ( tab[i] >= max ) {
        max = tab[i];
        j[k] = i;            
        k++;
    }
}
// print max values
for (k = 0; k < 12; k++) {
   if (j[k] != 0) {
       richTextBox1.Text = j[k].ToString();
       richTextBox1.Text = Environment.NewLine;
   }
}   

现在看到更多描述性的变量名称和更少硬编码的魔法常量:

private void PrintOutMaxValues() 
{
    int currentMax = 0;

    var input = new int[] { 3, 2, 5, 7, 1, 4, 4, 11, 3, 11, 11, 3 };
    var maxCounter = 0;

    // find max values
    for ( int inputIndex = 0; inputIndex < input.Length; inputIndex++) 
    {
        if ( input[ inputIndex ] > currentMax )
        {
           currentMax = input[ inputIndex ];
           maxCounter = 1;
        }
        else if ( input[ inputIndex ] == currentMax ) 
        {
           maxCounter++;
        }
    }

    //print out the maximum the number of times it occurred
    for ( var resultIndex = 0; resultIndex < maxCounter; resultIndex++) 
    {
        richTextBox1.Text += currentMax.ToString();
    }
}

代码“几乎”做同样的事情(因为我仍然不确定所需的输出),但正如您所见,为变量提供更长且更具描述性的名称可以更容易理解结果和意图开发人员:-)。在编码的情况下,有时更多实际上是更多,而不是更少;-)。编写一个字符的变量名称可以节省您编写的时间,但在尝试查找和修复无意中创建的错误时会花费更多。

【讨论】:

  • 下次我会更加注意我的代码的清晰度。你的回答很有帮助,谢谢:)
  • 当您开始编程时,这是最好的学习方法之一 :-)。祝你好运,编码愉快!
猜你喜欢
  • 2011-04-15
  • 2018-10-26
  • 1970-01-01
相关资源
最近更新 更多