跳轉到內容

更多 C++ 習語/命名迴圈

來自華夏公益教科書,開放的書籍,開放的世界

命名迴圈

[編輯 | 編輯原始碼]

部分模擬其他語言中找到的標記迴圈功能。

也稱為

[編輯 | 編輯原始碼]

標記迴圈

一些語言,如 Java 和 Perl,支援標記迴圈結構。在這些語言中,breakcontinue 關鍵字可以選擇指定先前定義的迴圈標籤來控制程式的流程。標記中斷將控制流從指定的迴圈中帶出,類似地,標記繼續從下一次迭代開始。標籤允許中斷和繼續不僅是最內層的迴圈,而且任何帶有標籤的外部迴圈。標記中斷和繼續可以提高使用巢狀迴圈的複雜程式碼的可讀性和靈活性。C++ 中的命名迴圈習語為該功能提供了部分支援。

解決方案和示例程式碼

[編輯 | 編輯原始碼]

命名迴圈習語使用 goto 實現。宏用於隱藏 goto 的顯式使用,這通常是被人不齒的。只有標記中斷語句可以使用以下兩個引數化宏來模擬。

#define named(blockname) goto blockname; \
                         blockname##_skip: if (0) \
                         blockname:

#define break(blockname) goto blockname##_skip

named(X) 宏定義了兩個 goto 標籤 XX_skip。break 宏是一個簡單的 goto 到 X_skip 標籤。示例如下。

struct test
{
  std::string str;
  test (std::string s) : str(s) { 
    std::cout << "test::test()::" << str << "\n"; 
  }
  ~test () { 
    std::cout << "~test::" << str << "\n"; 
  }
};

int main(void)
{
  named (outer) 
  for (int i = 0; i < 10; i++)
  {
    test t1("t1");
    int j = 0;
    named(inner)
    for (test t2("t2"); j < 5; j++)
    {
      test t3("t3");
      if (j == 1) break(outer);
      if (j == 3) break(inner);
      test t4("t4");
    }
    std::cout << "after inner\n";
  }
  return 0;
}

goto 不影響物件的正確構造和銷燬,如上述程式的輸出所證實。

test::test()::t1

test::test()::t2

test::test()::t3

test::test()::t4

~test::t4

~test::t3

test::test()::t3

~test::t3

~test::t2

~test::t1

已知用法

[編輯 | 編輯原始碼]
[編輯 | 編輯原始碼]

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書