如何继续工作?

时间:2014-07-28 13:53:48

标签: java for-loop while-loop break continue

我想了解"继续"作品。我理解了关键字的概念,但是当我运行不同的程序时,它的工作方式不同: - / 让我举几个例子:

如果我运行此程序:

int j = 0;
int i = 0;
LABEL1: for (; i < 3; i++) {
  if (true)
    continue;
}

i的价值将是3.到目前为止一直很好。 让我们添加一个外循环:

int j = 0;
int i = 0;
LABEL2: for (; j < 3; j++) {
  LABEL1: for (; i < 3; i++) {
    if (true)
      continue LABEL2;
  }
}

我的价值将是...... 0 !! 我不明白为什么如果继续使用带有转到外循环的标签,我不会增加。有人能解释一下为什么吗? 你有一些棘手的东西吗?还是做了一段时间?

我非常感谢您提供的任何帮助。

9 个答案:

答案 0 :(得分:28)

基本for语句结构如下:

BasicForStatement:
for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement

现在,来自JLS §14.14.1.3. Abrupt Completion of for Statement

  

如果语句的执行由于 continue没有标签而突然完成,则按顺序执行以下两个步骤:

     
      
  1. 首先,如果存在 ForUpdate 部分,则从左到右依次评估表达式;它们的值(如果有的话)被丢弃。如果 ForUpdate 部分不存在,则不采取任何措施。

  2.   
  3. 其次,执行另一个for迭代步骤。

  4.         

    如果语句的执行因 continue标签为L 而突然完成,则可以选择:

         
        
    • 如果for语句的标签为L,则按顺序执行以下两个步骤:

           
          
      1. 首先,如果存在 ForUpdate 部分,则从左到右依次评估表达式;它们的值(如果有的话)被丢弃。如果 ForUpdate 不存在,则不采取任何措施。

      2.   
      3. 其次,执行另一个for迭代步骤。

      4.   
    •   
    • 如果for语句没有标签L,则for语句突然完成,因为标签L继续。

    •   

(强调我的)

在您的情况下,

ForUpdate i++。基于以上内容:

  • 您的第一个代码段属于第一种情况,因此i会增加。

  • 您的第二个代码段属于第二种情况,因此i不会递增,因为for语句突然完成。

请注意,如果您的第二个代码段中有continue LABEL1,则i会像第一个代码段一样增加(根据JLS)。

作为未来的提示,对于语言规则/语义的权威性答案,您应该始终参考语言规范。对于Java,这是JLS

答案 1 :(得分:14)

这很正常。 exectuion流程是这样的:

  1. J = 0
  2. I = 0
  3. 输入LABEL 2循环,
  4. 输入了LABEL 1循环,
  5. 继续参阅LABEL 2
  6. J ++
  7. 输入了LABEL 1循环,
  8. 继续参阅LABEL 2
  9. J ++
  10. 输入了LABEL 1循环,
  11. 继续使用LABEL 2 ......直到j == 3

答案 2 :(得分:7)

i会在内循环结束时增加。但是continue LABEL2跳出内循环,到外循环的末尾,所以i没有增加;相反,只有j增加,直到不再满足外循环条件。

当我们用while循环重写代码时,可能会更清楚:

int j=0;
int i = 0;
while (j<3) {
    while(i<3) {
       if (true)
           goto END_OF_LOOP2;

       END_OF_LOOP1: i++;
    }
    END_OF_LOOP2: j++;
}

答案 3 :(得分:6)

继续简单地按照其名称建议,它会立即继续执行循环,而不执行循环中的其余代码。

所以如果你有这样的循环:

int j=0;
int i = 0;
    LABEL1 : for(;i < 3; i++){
        if (true) {
            continue;
        }
        someOtherMethod();
    }

someOtherMethod部分永远不会被执行,因为你总会点击继续。

您的计数器永不递增的原因与标签有关,您可以使用标签标记循环(在您的情况下为LABEL1LABEL2并使用该标签继续其中一个外循环内循环。

因此,对于您的代码,LABEL1的循环永远不会有机会增加其计数器,因此i仍然是0,因为您的continue语句会立即继续到外循环的下一次迭代

答案 4 :(得分:4)

continue LABEL2; 

导致只有外环增加。如果你有

LABEL2 : for(;j <3;j++){
    LABEL1 : for(;i < 3; i++){
             if (true)
                 continue LABEL1;
             }
     }

i会增加。

答案 5 :(得分:3)

如果这是代码, 例如:

    int main (){
      // Local variable declaration:

    int a = 10;

   // do loop execution
  do
  {
     if( a == 15)
     {
        // skip the iteration.
        a = a + 1;
        continue;
      }
      cout << "value of a: " << a << endl;
           a = a + 1;
         }while( a < 20 );
         return 0;
     }

然后结果将是

value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19

要注意的要点: “a:15的值”不在输出中。 继续编程语言会跳过循环中的某一行,如果使用“break”,那么break就会在“14”之后离开该行(在这种情况下)。
为了您的理解,请参阅以下流程图:

enter image description here

答案 6 :(得分:3)

  

i 会在检查下一个时间条件时递增。

如果您continuebreak循环,则不会再次检查条件,也不会增加i的值。

代表

LABEL1 : for(;i < 3; i++){
               if (true)
                   continue;
             }

当你继续检查条件编译器内部增加i的值时,再次检查i的值是否小于3。

这里

LABEL2 : for(;j <3;j++){
        LABEL1 : for(;i < 3; i++){
                 if (true)
                     continue LABEL2;
                 }
         }

当您执行continue Label1时,Label2的条件永远不会再次检查,并会直接转到LABEL1 : for(;i < 3; i++){ if (true) break; } 的语句,因此它永远不会增加。

同样是休息

i

如果您执行上述代码值0将为1而不是{{1}}。

答案 7 :(得分:2)

如果在调试模式下运行,您将看到会发生什么。简而言之,无论何时进入内部循环以增加i,您都将continue改为LABEL2而不是递增i并转到内循环的下一次迭代

因此,你将在外循环3次,你将永远不会在内循环中点击i++

如果它更容易,可以将内部for循环视为while循环:

int i = 0, j = 0;
LABEL2: for (; j < 3; j++) {
  LABEL1: while (i < 3) {
    if (true) {
      continue LABEL2;
    }

    i++;
  }
}

答案 8 :(得分:0)

没有标签的continue语句将从最里面的while或do,或循环的条件重新执行,并从更新表达式重新执行最里面的for循环。它通常用于提前终止循环处理,从而避免深度嵌套的if语句。在以下示例中,continue将获取下一行,而不在循环中处理以下语句。

while (getNext(line)) {
  if (line.isEmpty() || line.isComment())
    continue;
  // More code here
}

使用标签,continue将以相应标记的循环执行。这可以用于逃避深层嵌套循环,或者仅为了清楚起见。如果你真的有悖常理,你也可以用它来模拟有限形式的goto。在以下示例中,continue将重新执行for (;;)循环。

aLoopName: for (;;) {
  // ...
  while (someCondition)
  // ...
    if (otherCondition)
      continue aLoopName;

有时continue也会用作占位符,以使空循环体更清晰。

for (count = 0; foo.moreData(); count++)   continue;

C和C ++中也存在没有label的相同语句。在Perl中,它被命名为next

source