2014-04-29 72 views
2

我知道C++ 03不允許在switch塊中定義變量而不使用 大括號。C++ 11:聲明switch語句中的變量

const int i = ... 
switch (i) { case 0: int j = 0; break; } // 1. error here 
switch (i) { case 0: { int j = 0; } break; } // 2. ok 

什麼是關於新的C++ 11標準? 它允許第一種形式嗎? 我也可以這樣寫:

switch (i) 
{ 
    case 0: int j = 0; break; 
    case 1: int j = 0; break; 
    case 2: int j = 0; break; 
} 
+0

那麼,還是要用塊。另外,你的第一個例子有點混亂,只是FYI。 – sircodesalot

+0

第一個例子中的錯誤是什麼?對我來說看起來很好。還是你的意思是到處使用'i',而不是'i'和'j'? – Praetorian

+0

我只想說,我們有選擇 - 我和定義distictly命名爲另一個變量 - J – 4xy

回答

0

你不能寫這個,因爲範圍問題。您的代碼將導致的可變j

重新定義在代碼:

const int i = ... 
switch (i) { case 0: int j = 0; break; } // the error should be linked to default statement that is not there 
switch (i) { case 0: { int j = 0; } break; } // here you define a local scope in which you can define `j` ; j will be destroyed after the closing bracket. 

即使在C++ 11,試圖做到這一點:

switch (i) 
{ 
    case 0: int j = 0; break; 
    case 1: int j = 0; break; 
    case 2: int j = 0; break; 
} 

導致同樣的錯誤比如果你想寫:

for (; ;) { 
     int i = 0 ; 
     int i = 0 ; 
     int i = 0 ; 
} 

這將導致重新定義錯誤

+0

那是不是該禁止的原因,見[這個問題](http://stackoverflow.com/questions/92396/why- cant-variables-be-decla-in-a-switch-statement)出於真實原因(跳過初始化)。 – rubenvb

4

case聲明沒有(在C++ 03中),仍然沒有(在C++ 11中)引入一個範圍。

標準說,在[stmt.switch](6.4.2/6):在本身

情況和默認標籤不改變 控制,繼續過這種標籤暢通的流動。

因此它被允許這樣「砸鍋」 case聲明:

int x, a = 1; 
switch(a) { 
case 1: 
    x = 5; 
    // no break here! 
case 10: 
    x *= 4; // x is now 20. 
} 

如果你想下面介紹第一case聲明例如varible聲明,它可能被跳過時跳轉到第二個case聲明會發生。

但是,您可以在switch塊的開始聲明一個局部變量權:

switch (i) 
{ 
    int j; 
case 0: j = 0; break; 
case 1: j = 0; break; 
case 2: j = 0; break; 
} 

一個switch真的超過了一系列if/else if語句跳轉表。

+0

我從來不知道你可以在第一個case標籤之前聲明變量。 –

+0

@MarkRansom你可以有相當多的東西在那裏('開關(3){看跌期權(「咦?!」);}'),這幾乎是從來沒有有用的,但聲明一個變量是爲數不多的例外情況是非常有用的一個。 – hvd

+1

@MarkRansom:別的東西相似的,有趣的,也許令人驚訝的是一個可以用switch語句做的是[達夫設備(http://en.wikipedia.org/wiki/Duff's_device)。如果你從未見過它,那麼值得一看。本質上,你將一個循環的主體與開關的主體交錯,以便在跳過一些可變數量的第一次迭代的同時展開一個循環。 – Apriori

1

C++ 03當然允許您在switch語句的主體中定義變量。該機構是不是在所有的任何其他複合語句不同,用於跳轉到一個標籤規則適用同樣的方式:你只能跳進

  • 標類型的範圍內聲明沒有初始化
  • 類類型瑣碎默認構造和瑣碎析構函數聲明沒有初始化的上述

這些規則

  • 陣列沒有改變在C++ 11。

    #include <iostream> 
    int main() 
    { 
        int n; 
        std::cin >> n; 
    
        switch(n) 
        { 
           int a;  // okay, scalar with no initializer 
         case 1: int b = 10; // okay, no more labels, no way jump into scope 
           a = b = 3*n; 
           break; 
        }