[英]How does continue work?
我試圖了解“繼續”的工作原理。 我理解了關鍵字的概念,但是當我運行不同的程序時,它的工作方式不同: - /讓我向您展示一些示例:
如果我運行這個程序:
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 !! 我不明白為什么如果繼續使用帶有轉到外部循環的標簽,我不會增加。 有人能解釋一下為什么嗎? 你有一些棘手的東西嗎? 還是做了一段時間?
我非常感謝您提供的任何幫助。
基本for
語句結構如下:
BasicForStatement: for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement
現在,來自JLS§14.14.1.3。 突然完成for
聲明 :
如果由於沒有標簽的
continue
而突然完成Statement的執行,則按順序執行以下兩個步驟:
首先, 如果存在ForUpdate部分 , 則從左到右依次評估表達式 ; 它們的值(如果有的話)被丟棄。 如果ForUpdate部分不存在,則不執行任何操作。
第二,另一個
for
迭代步驟中進行。如果由於
continue
使用標簽L
突然完成Statement的執行,則可以選擇:
如果
for
語句具有標簽L
,則按順序執行以下兩個步驟:
首先,如果存在ForUpdate部分,則從左到右依次評估表達式; 它們的值(如果有的話)被丟棄。 如果ForUpdate不存在,則不執行任何操作。
第二,另一個
for
迭代步驟中進行。如果
for
語句沒有標簽L
,則for
語句突然完成,因為標簽L
繼續。
(強調我的)
在你的情況下, ForUpdate是i++
。 基於以上內容:
你的第一個片段屬於第一種情況,所以i
增加了。
你的第二個片段屬於第二種情況,所以i
沒有增加,因為for
語句突然完成。
請注意,如果您在第二個片段中continue LABEL1
, i
將按照您的第一個片段(根據JLS)增加。
作為未來的提示,關於語言規則/語義的明確答案,您應該始終參考語言規范。 對於Java,那就是JLS 。
這很正常。 exectuion流程如下:
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++;
}
繼續簡單地做它的名字所暗示的,它會立即繼續循環的下一次執行而不執行循環中的其余代碼。
所以,如果你有這樣的循環:
int j=0;
int i = 0;
LABEL1 : for(;i < 3; i++){
if (true) {
continue;
}
someOtherMethod();
}
someOtherMethod部分永遠不會執行,因為您將始終點擊繼續。
您的計數器永遠不會增加的原因與標簽有關,您可以使用標簽標記循環(在您的情況下為LABEL1
和LABEL2
並使用該標簽繼續內循環的一個外循環。
因此,對於您的代碼, LABEL1
的循環永遠不會有機會增加其計數器,因此i
保持為0
因為您的continue語句會立即繼續到外循環的下一次迭代。
continue LABEL2;
導致只有外部循環增加。 如果你有
LABEL2 : for(;j <3;j++){
LABEL1 : for(;i < 3; i++){
if (true)
continue LABEL1;
}
}
i
會增加。
如果這是代碼,例如:
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”之后離開該行(在這種情況下)。
為了便於您理解,請參閱以下流程圖:
檢查下一次條件時,
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
。
如果在調試模式下運行它,您將看到會發生什么。 簡而言之,每當你進入內部循環來增加i
,你將continue
使用LABEL2
而不是遞增i
並進入內循環的下一次迭代。
因此,你將在外循環3次,你永遠不會在內循環中擊中i++
。
如果它更容易,可以像while循環一樣考慮內部for循環:
int i = 0, j = 0;
LABEL2: for (; j < 3; j++) {
LABEL1: while (i < 3) {
if (true) {
continue LABEL2;
}
i++;
}
}
沒有標簽的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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.