Попытка понять ярлык / прыжок в Java [дубликат]

29
задан Xinzz 28 July 2014 в 15:14
поделиться

8 ответов

Основная структура оператора for выглядит следующим образом:

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

Теперь из JLS §14.14.1.3. Резкое завершение for Statement :

Если выполнение Statement завершается внезапно из-за continue без метки, то следующие два шаги выполняются последовательно:

  1. Во-первых, если присутствует ForUpdate часть, выражения оцениваются последовательно слева направо; их значения, если они есть, отбрасываются. Если ForUpdate нет, никаких действий не предпринимается.
  2. Во-вторых, выполняется еще один шаг итерации for.

Если выполнение Statement завершается внезапно из-за continue с меткой L, тогда есть выбор:

  • Если оператор for имеет метку L, то следующие последовательности выполняются последовательно: во-первых, если присутствует ForUpdate часть, выражения оцениваются последовательно слева направо; их значения, если они есть, отбрасываются. Если ForUpdate отсутствует, никаких действий не предпринимается. Во-вторых, выполняется еще один шаг итерации for.
  • Если оператор for не имеет метки L, оператор for неожиданно завершается из-за продолжения с меткой L.

(выделение мое)

ForUpdate , в вашем случае, i++. На основании того, что выше:

  • Ваш первый фрагмент относится к первому случаю, поэтому i увеличивается.
  • Второй фрагмент подпадает под второй случай, поэтому i не увеличивается, потому что инструкция for завершается внезапно.

Обратите внимание, что если бы во втором фрагменте continue LABEL1, i был бы увеличен, как в вашем первом фрагменте ( в соответствии с JLS).

В качестве подсказки для будущего, для окончательных ответов относительно языковых правил / семантики, вы должны всегда проконсультироваться с языком Спецификация. Для Java это JLS .

28
ответ дан arshajii 25 August 2018 в 13:22
поделиться

Оператор continue без метки будет повторно выполняться из условия, которое является самым внутренним во время или до, или циклом, и из выражения update - самым внутренним для цикла. Он часто используется для раннего завершения обработки цикла и, тем самым, для избежания глубоко вложенных операторов 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;

Тот же оператор без label также существует в C и C ++. В Perl он называется next.

source

0
ответ дан Community 25 August 2018 в 13:22
поделиться

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++;
}
7
ответ дан Erich Kitzmueller 25 August 2018 в 13:22
поделиться

i увеличивается, когда проверяется следующее условие времени.

Если вы continue или break, тогда цикл не будет проверяться снова и никогда не будет увеличивайте значение i.

для

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

, когда вы продолжаете, вы снова проверяете, если значение i меньше 3 в этот момент, прежде чем проверять, что компилятор условия внутренне увеличивает значение i.

Здесь

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.

3
ответ дан Parth 25 August 2018 в 13:22
поделиться

Продолжение просто делает то, что предлагает его имя, оно немедленно продолжает следующее выполнение цикла без выполнения остальной части кода в цикле.

Итак, если у вас есть такой цикл:

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

Часть someOtherMethod никогда не выполняется, потому что вы всегда будете нажимать на продолжение.

Причина, по которой ваш счетчик никогда не увеличивается, связан с метками, вы можете пометить цикл меткой (в вашем случае LABEL1 и LABEL2 и используйте эту метку, чтобы продолжить одну из внешних циклов вашего внутреннего цикла.

Таким образом, с вашим кодом цикл LABEL1 никогда не будет иметь шансов на увеличение его счетчик и, следовательно, i остаются 0, потому что ваш оператор продолжения немедленно продолжает следующую итерацию внешнего цикла.

6
ответ дан Remcoder 25 August 2018 в 13:22
поделиться

Если это код, например:

    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», а затем разрывается, просто выходит из этой строки после «14» (в данном случае). Для вашего понимания см. Следующую блок-схему:

enter image description here [/g0]

3
ответ дан Shayan Ahmad 25 August 2018 в 13:22
поделиться

Если вы запустите это в режиме отладки, вы увидите, что произойдет. Короче говоря, всякий раз, когда вы вводите внутренний цикл для увеличения i, вместо LABEL2 вместо i вы будете вместо continue вместо i и переходите к следующей итерации внутреннего цикла.

Таким образом, вы будете во внешнем цикле 3 раза, и вы никогда не ударите i++ во внутреннем цикле.

Если это проще, подумайте о внутреннем цикле, как цикл while:

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

    i++;
  }
}
14
ответ дан Xinzz 25 August 2018 в 13:22
поделиться
continue LABEL2; 

вызывает увеличение только внешнего цикла. если у вас

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

i будет увеличиваться.

4
ответ дан Zhenxiao Hao 25 August 2018 в 13:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: