Подтвердить что ты не робот

Как продолжать работу?

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

Если я запустил эту программу:

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

Значение я будет равно 3. настолько хорошо. Пусть добавлен внешний цикл:

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

Значение я будет... 0!! Я не понимаю, почему я не увеличивается, если continue используется с меткой, которая идет во внешний цикл. Может ли кто-нибудь объяснить это почему? У вас есть такие сложные вещи, как перерыв? или с помощью do {} while?

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

4b9b3361

Ответ 1

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

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

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

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

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

  • Во-вторых, выполняется еще один шаг итерации for.

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

  • Если оператор for имеет метку L, то следующие последовательности выполняются последовательно:

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

    • Во-вторых, выполняется еще один шаг итерации for.

  • Если оператор for не имеет метки L, оператор for завершается внезапно из-за продолжения с меткой L.

(акцент мой)

ForUpdate, в вашем случае, i++. Основываясь на том, что выше:

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

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

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

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

Ответ 2

Это действительно нормально. Поток exectuion выглядит следующим образом:

  • J = 0
  • = 0
  • Включен цикл LABEL 2,
  • введен LABEL 1,
  • продолжаем LABEL 2
  • J ++
  • введен LABEL 1,
  • продолжаем LABEL 2
  • J ++
  • введен LABEL 1,
  • продолжаем LABEL 2 ... до j == 3

Ответ 3

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++;
}

Ответ 4

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

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

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

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

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

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

Ответ 5

continue LABEL2; 

приводит к увеличению только замыкания петли. если у вас есть

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

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

Ответ 6

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

    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

Ответ 7

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.

Ответ 8

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

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

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

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

    i++;
  }
}

Ответ 9

Оператор

A continue без метки повторно выполнит из условия самое внутреннее время while или do или цикл, а из выражения 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 и С++. В Perl он назван next.

источник