2017-03-06 55 views
-6

我對輸入和輸出感到困惑,誰能告訴我爲什麼我會得到這樣的輸出。開關盒中的逗號

#include<iostream> 
#include<stdlib.h> 
using namespace std; 

int main() 
{ 
    int ival, oddcnt(0), evencnt(0); 
    while (cin >> ival) { 
     switch (ival) { 
     case 1, 3, 5, 7, 9: 
      oddcnt++; 
      break; 
     case 2, 4, 6, 8, 10: 
      evencnt++; 
      break; 
     } 
    } 
    cout << "Quantity of odd number:" << oddcnt << "\n" 
     << "Quantity of even number:" << evencnt << endl; 
    system("pause"); 
    return 0; 
} 

這是結果獲得: 輸入:1 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 6 6 6 7 7 7 7 8 8 9 9 10 10 10 EOF 輸出:奇數的數量:2 數量偶數:3 enter image description here

+3

我無法訪問您的圖像用我的工作場所的輸出,你能寫下來嗎? –

+1

是什麼讓你認爲'case 1,3,5,7,9:'是有效的C++? –

+0

我猜測它只能檢查9和10。 [在逗號運算符上的某些帖子](http://stackoverflow.com/questions/54142/how-does-the-comma-operator-work) – JGroven

回答

4

逗號在case標籤這種用法是非法的標準C++。這在語法上是不正確的。一致性編譯器必須發佈診斷消息來響應此代碼,即使它以某種方式接受它。

有可能(或可能不)涉及一些複雜的細節。

  • 在原來的C++ 98語言逗號運算符被禁止使用的形式被用於case標籤。它被語言規範的兩個不同部分「封鎖」:

    首先,constant-expression的語法不允許在常量表達式中使用頂級逗號運算符。在語法上,逗號運算符只能出現在包含在()中的常量表達式中。其次,C++ 98規範明確禁止在嵌套()(見5.19/1)的任何級別的常量表達式中使用逗號運算符。

    (這是基本相同的C語言的要求。)

  • 然而,C++ 11做了一些改變:它allowed comma operator in constant expressions。然而,語法沒有改變。這意味着逗號運算符現在允許使用常量表達式,但只能在()中使用。例如。從C++ 11開始,你可以使用

    case (1, 3, 5, 7, 9): 
    

    這是一個普通的逗號運算符。它使相當於

    case 9: 
    

同時整個事情,你

case 1, 3, 5, 7, 9: 

仍然用C++非法的這一天。如果你的編譯器以某種方式支持它,它必須是你的編譯器實現的語言擴展。請查閱您的編譯器文檔以確定它的含義。

通過您得到的輸出來判斷,編譯器將case 1, 3, 5, 7, 9:視爲等效於case (1, 3, 5, 7, 9):,因此等於case 9:。這解釋了輸出。該程序只是在輸入中計數9 s和10 s。你有兩個9 s和三個10 s。

參見:
Is the comma operator allowed in a constant-expression in C++11?
Why was the restriction on the comma operator being in a constant expression removed in C++11?

+0

那麼,正如OP中提到的那樣,編譯器拿了那個,併產生了一些輸出?你確定這個騙局在這裏被錯誤地應用了嗎? –

+0

我更喜歡你的情況(1,3,5,7,9):解決方案比我的答案。不能說你有215K沒有任何東西:) –

+0

[http://stackoverflow.com/questions/42618651/comma-in-switch-case] _italic_ ** bold **'code'你的解釋在這裏有道理。起初,考慮到逗號的低優先級,我想不出爲什麼它不計算1和2的數目。我想,嘗試一個可以運行的錯誤程序很有趣。謝謝你的解釋。 – Higher

0
switch (var) { 
    case value1: /* ... */ break; 
    case value2: /* ... */ break; 
    /* ... */ 
} 
2

可以嘗試這代替開關內部:

switch (ival) { 
    case 1: 
    case 3: 
    case 5: 
    case 7: 
    case 9: 
    oddcnt++; 
    break; 

    case 2: 
    case 4: 
    case 6: 
    case 8: 
    case 10: 
    evencnt++; 
    break; 
} 
+1

或者他們可以丟棄'switch'並使用模數運算符。 'ival%2'是一個很好的偶數/奇數檢測器。 – user4581301

+0

是的,其實你的答案會更好,更短。但我只是寫了如何製作一個以他想要的方式工作的開關。 –

0
switch (ival) { 
     case 1, 3, 5, 7, 9: 
      oddcnt++; 
      break; 
     case 2, 4, 6, 8, 10: 
      evencnt++; 
      break; 
     } 

殼體1,3,5,7,9: 這種類型的switch語句會導致語法錯誤,但在您的情況下卻沒有。

語法錯誤(在編譯器gcc版本5.4.0(GCC)):

error: expected ‘:’ before ‘,’ token 
     case 1, 3, 5, 7, 9: 
      ^
error: expected ‘:’ before ‘,’ token 
    case 2, 4, 6, 8, 10: 
     ^
error: expected primary-expression before ‘,’ token 

不過你可以試試下面的開關情況:

switch (ival) { 
     case 1: 
     case 3: 
     case 5: 
     case 7: 
     case 9: 
      oddcnt++; 
      break; 
     case 2: 
     case 4: 
     case 6: 
     case 8: 
     case 10: 
      evencnt++; 
      break; 
     } 
+0

它顯然不會導致OP示例中的語法錯誤。 –

+0

我想知道它是如何通過編譯? :D –

+0

沒問題,因爲@AnT的回答可能是由於OP的編譯器提供的擴展... –