亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么不能在開關語句中聲明變量?

為什么不能在開關語句中聲明變量?

C++ C
慕斯709654 2019-05-31 17:09:15
為什么不能在開關語句中聲明變量?我一直在想,為什么不能在開關語句中的CASE標簽之后聲明變量呢?在C+中,您可以在任何地方聲明變量(并且聲明它們接近第一次使用顯然是件好事),但是下面的內容仍然不能工作:switch (val)  {  case VAL:     // This won't work   int newVal = 42;     break;case ANOTHER_VAL:     ...   break;}以上給出了以下錯誤(MSC):“newVal”的初始化由“case”標簽跳過在其他語言中,這似乎也是一個限制。為何會出現這樣的問題呢?
查看完整描述

3 回答

?
呼啦一陣風

TA貢獻1802條經驗 獲得超6個贊

Case陳述僅限于標簽..這意味著編譯器將解釋為直接跳轉到標簽。在C+中,這里的問題是范圍問題之一。您的花括號將作用域定義為switch聲明。這意味著您將有一個范圍,在該范圍內,將在代碼中執行跳轉,跳過初始化。正確的處理方法是定義一個特定于case語句,并在其中定義變量。

switch (val){   case VAL:  {
  // This will work
  int newVal = 42;  
  break;}case ANOTHER_VAL:  ...break;}


查看完整回答
反對 回復 2019-05-31
?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

這個問題最初被標記為[C]和[C+]。原來的代碼在C和C+中都是無效的,但是由于完全不同的原因。我相信這個重要的細節被現有的答案所遺漏(或混淆)。

  • 在C+中,此代碼無效,因為case ANOTHER_VAL:標簽跳入變量的范圍。newVal繞過它的初始化。跳過本地對象的初始化在C+中是非法的。大多數答案都正確地處理了這個問題的這一面。

  • 但是,在C語言中,繞過變量初始化并不是一個錯誤。在初始化時跳入變量的范圍在C中是合法的。它只是意味著變量沒有初始化。由于完全不同的原因,原始代碼沒有在C中編譯。標簽case VAL:在原始代碼中,變量的聲明附加在一起。newVal..在C語言中,聲明不是語句。他們不能被貼上標簽。當這段代碼被解釋為C代碼時,這就是導致錯誤的原因。

    switch (val)  {  case VAL:             /* <- C error is here */
      int newVal = 42;  
      break;case ANOTHER_VAL:     /* <- C++ error is here */
      ...
      break;}

加一個額外的{}塊修復了C+和C兩個問題,盡管這些問題恰好不同。在C+方面,它限制了newVal,確保case ANOTHER_VAL:不再跳入該范圍,從而消除了C+問題。在C邊那額外的{}引入復合語句,從而使case VAL:標簽可應用于語句,從而消除了C問題。

  • 在C情況下,這個問題可以很容易地解決,而不需要{}..之后添加一個空語句即可。case VAL:標簽和代碼將變得有效。

    switch (val)  {  case VAL:;            /* Now it works in C! */
      int newVal = 42;  
      break;case ANOTHER_VAL:  
      ...
      break;}

    注意,盡管從C的角度來看,它現在是有效的,但從C+的角度來看,它仍然是無效的。

  • 對稱地說,在C+情況下,這個問題可以很容易地解決,而不需要{}..只要從變量聲明中刪除初始化程序,代碼就會生效。

    switch (val)  {  case VAL: 
      int newVal;
      newVal = 42;  
      break;case ANOTHER_VAL:     /* Now it works in C++! */
      ...
      break;}

    注意,盡管從C+的角度來看,它現在是有效的,但從C的角度來看,它仍然是無效的。


查看完整回答
反對 回復 2019-05-31
?
Qyouu

TA貢獻1786條經驗 獲得超11個贊

好的。嚴格地澄清這一點與聲明無關。它只涉及“跳過初始化”(ISO C+‘03 6.7/3)

這里的許多帖子提到,跳過聲明可能會導致變量“未聲明”。這不是真的。POD對象可以在沒有初始化器的情況下被聲明,但是它有一個不確定的值。例如:

switch (i){
   case 0:
     int j; // 'j' has indeterminate value
     j = 0; // 'j' initialized to 0, but this statement
            // is jumped when 'i == 1'
     break;
   case 1:
     ++j;   // 'j' is in scope here - but it has an indeterminate value
     break;}

如果對象是非POD或聚合,編譯器將隱式添加初始化器,因此不可能跳過這樣的聲明:

class A {public:
  A ();};switch (i)  // Error - jumping over initialization of 'A'{
   case 0:
     A j;   // Compiler implicitly calls default constructor
     break;
   case 1:
     break;}

此限制不限于開關語句。使用“goto”跳過初始化也是一個錯誤:

goto LABEL;    // Error jumping over initializationint j = 0; LABEL:
  ;

有一點需要注意的是,這是C+和C之間的區別,在C中,跳過初始化并不是一個錯誤。

正如其他人所提到的,解決方案是添加一個嵌套塊,以便變量的生存期僅限于個別的CASE標簽。


查看完整回答
反對 回復 2019-05-31
  • 3 回答
  • 0 關注
  • 824 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號