Как продолжать работу?
Я пытаюсь понять, как работает "продолжить". Я понял концепцию ключевого слова, но когда я запускаю разные программы, он работает по-другому: -/
Позвольте мне показать вам несколько примеров:
Если я запустил эту программу:
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?
Я очень ценю любую помощь, которую вы можете предоставить.
Ответы
Ответ 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
.
источник