我想了解"继续"作品。我理解了关键字的概念,但是当我运行不同的程序时,它的工作方式不同: - / 让我举几个例子:
如果我运行此程序:
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 !! 我不明白为什么如果继续使用带有转到外循环的标签,我不会增加。有人能解释一下为什么吗? 你有一些棘手的东西吗?还是做了一段时间?
我非常感谢您提供的任何帮助。
答案 0 :(得分:28)
基本for
语句结构如下:
BasicForStatement: for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement
现在,来自JLS §14.14.1.3. Abrupt Completion of for
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。
答案 1 :(得分:14)
这很正常。 exectuion流程是这样的:
答案 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部分永远不会被执行,因为你总会点击继续。
您的计数器永不递增的原因与标签有关,您可以使用标签标记循环(在您的情况下为LABEL1
和LABEL2
并使用该标签继续其中一个外循环内循环。
因此,对于您的代码,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”之后离开该行(在这种情况下)。
为了您的理解,请参阅以下流程图:
答案 6 :(得分:3)
i
会在检查下一个时间条件时递增。
如果您continue
或break
循环,则不会再次检查条件,也不会增加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
。