0

我有 2 个 for 循环,一个嵌套在另一个循环中。它们循环遍历按钮的 2D 数组,以获取使用动作侦听器单击的每个按钮的源。

找到按钮后,我将按钮的位置/数组索引传递给外部方法。但是,当从按钮数组中找到按钮时,第一个 for 循环将其终止条件评估为 FALSE,但仍会增加 i 的值。导致一个错误。我的代码在标准操作执行方法中,“事件”是 ActionEvent。button[][] 是一个定义为实例变量的 JButton 数组。它的大小为 10 x 10,并且已添加到面板中。

int i = 0; //this will loop through the columns in the array
int j  = 0; //loop through the rows
boolean locatedSource = false; //allows me to escape both loops

for(i = 0; !(locatedSource) && i < buttons.length; i++) //problem here, when i < buttons.length is FALSE i still gets incremented, leading to an off by one error
{
  for(j = 0; !(locatedSource) && j < buttons.length; j++)
  {
    if(event.getSource() == buttons[i][j])
    {
      locatedSource = true;
      break;
    }
  }
}
//do stuff with i and j in another method. Leads to array out of bounds error / off by one error
}

我应该提到,我不想通过使用标签来解决这个问题,他们似乎不鼓励。

4

4 回答 4

1

使用一些布尔标志将其设置在内循环中并在外循环的开头检查它。

这是代码:

    boolean found = false;
    for (i = 0; i < 10; i++) // problem here, when i < buttons.length is FALSE i still gets
                             // incremented, leading to an off by one error
    {
        if (found) {
            i--;
            break;
        }
        for (j = 0; j < 5; j++) {
            if (i == 5 && j == 3) {
                found = true;
                break;
            }
        }
        //if (found) {               
        //    break;
        //}
    }
于 2014-03-09T15:31:16.680 回答
1

三种可能的解决方案:

  1. 明确设置“找到”索引,不要重复使用for循环索引。
  2. 在自己的方法中return直接从循环中搜索。
  3. i完成循环后减1。
于 2014-03-09T15:31:22.947 回答
1

您的代码包含注释“这里的问题,当 i <buttons.length 为 FALSE 时,我仍然会增加,导致关闭一个错误”,这在事件的顺序上是错误的。

首先循环更新块被执行(就像i++)然后检查条件(像'i <buttons.length')。

意思是,即i == buttons.length循环结束后没有触发locatedSource条件的正确状态。

于 2014-03-09T15:53:25.363 回答
1

问题的解释

for 循环的增量表达式在每次循环迭代之后而不是之前执行。请参阅Oracle Java 教程中的以下引用:

for 语句提供了一种迭代一系列值的紧凑方法。程序员经常将其称为“for 循环”,因为它反复循环直到满足特定条件。for 语句的一般形式可以表示为:

for (initialization; termination;
     increment) {
    statement(s)
}

使用此版本的 for 语句时,请记住:

  1. 初始化表达式初始化循环;它在循环开始时执行一次。
  2. 当终止表达式的计算结果为 false 时,循环终止。
  3. 每次循环迭代后都会调用增量表达式;这个表达式增加或减少一个值是完全可以接受的。

For循环解决方案

您可以重新编写循环,以便增量是循环内的第一条语句。

    for (i = 0; !(locatedSource) && i < buttons.length;) {
        i++;
        for (j = 0; !(locatedSource) && j < buttons.length;) {
            j++;
            if (event.getSource() == buttons[i][j]) {
                locatedSource = true;
            }
        }
    }

While 循环版本

鉴于循环变量都是在循环之外初始化的,并且您不想使用 for 循环增量表达式,因此重写代码以使用 while 循环可能会更清晰,如下所示:

    while (!(locatedSource) && i < buttons.length) {
        i++;
        while (!(locatedSource) && j < buttons.length) {
            j++;
            if (event.getSource() == buttons[i][j]) {
                locatedSource = true;
            }
        }
    }
于 2014-03-09T15:59:50.157 回答