簡體   English   中英

如何繼續工作?

[英]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的執行,則按順序執行以下兩個步驟:

  1. 首先, 如果存在ForUpdate部分從左到右依次評估表達式 ; 它們的值(如果有的話)被丟棄。 如果ForUpdate部分不存在,則不執行任何操作。

  2. 第二,另一個for迭代步驟中進行。

如果由於continue使用標簽L突然完成Statement的執行,則可以選擇:

  • 如果for語句具有標簽L ,則按順序執行以下兩個步驟:

    1. 首先,如果存在ForUpdate部分,則從左到右依次評估表達式; 它們的值(如果有的話)被丟棄。 如果ForUpdate不存在,則不執行任何操作。

    2. 第二,另一個for迭代步驟中進行。

  • 如果for語句沒有標簽L ,則for語句突然完成,因為標簽L繼續。

(強調我的)

在你的情況下, ForUpdatei++ 基於以上內容:

  • 你的第一個片段屬於第一種情況,所以i增加了。

  • 你的第二個片段屬於第二種情況,所以i沒有增加,因為for語句突然完成。

請注意,如果您在第二個片段中continue LABEL1i將按照您的第一個片段(根據JLS)增加。

作為未來的提示,關於語言規則/語義的明確答案,您應該始終參考語言規范。 對於Java,那就是JLS

這很正常。 exectuion流程如下:

  1. J = 0
  2. I = 0
  3. 輸入LABEL 2循環,
  4. 輸入LABEL 1循環,
  5. 繼續LABEL 2
  6. J ++
  7. 輸入LABEL 1循環,
  8. 繼續LABEL 2
  9. J ++
  10. 輸入LABEL 1循環,
  11. 繼續到LABEL 2 ...直到j == 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++;
}

繼續簡單地做它的名字所暗示的,它會立即繼續循環的下一次執行而不執行循環中的其余代碼。

所以,如果你有這樣的循環:

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

someOtherMethod部分永遠不會執行,因為您將始終點擊繼續。

您的計數器永遠不會增加的原因與標簽有關,您可以使用標簽標記循環(在您的情況下為LABEL1LABEL2並使用該標簽繼續內循環的一個外循環。

因此,對於您的代碼, 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會增加。

如果continuebreak循環,則不會再次檢查條件,並且永遠不會增加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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM