2015-11-13 37 views
5

我知道這段代碼不能像預期的那樣工作。這段代碼只是快速尋找,我們認爲返回值應該是1,但在執行它返回返回3在開關中不正確的多個案例不會產生編譯器錯誤

// incorrect 
variable = 1; 
switch (variable) 
{ 
    case 1, 2: 
    return 1; 
    case 3, 4: 
    return 2; 
    default: 
    return 3; 
} 

,並有一些正確的選項要做到這一點:

// correct 1 
variable = 1; 
switch (variable) 
{ 
    case 1: case 2: 
    return 1; 
    case 3: case 4: 
    return 2; 
    default: 
    return 3; 
} 

// correct 2 
switch (variable) 
{ 
    case 1: 
    case 2: 
    return 1; 
    case 3: 
    case 4: 
    return 2; 
    default: 
    return 3; 
} 

Multiple Cases in Switch:

部分回答我願意想知道爲什麼不正確的形式編譯時沒有錯誤或甚至警告(至少在Borland C++編譯器中)。

編譯器在該代碼中的理解是什麼?

+3

值的事實[如何逗號操作符的工作?](HTTP://計算器。 com/questions/54142 /如何做這個逗號操作工) –

回答

8

這段代碼就趕緊找,我們認爲返回值應該是1,

我想說的是有經驗的C++開發人員會立即發現,什麼是錯的,並很快得出結論,其他一些程序員不小心用逗號:,

,但在執行它返回返回3

否,代碼不得編譯,因爲案件的表達是不恆定的

而作爲事實上,它在任何中途現代編譯器來編譯。例如,MSVC 2013表示:

stackoverflow.cpp(8) : error C2051: case expression not constant 
stackoverflow.cpp(10) : error C2051: case expression not constant 

1, 2表達式是逗號運算符的應用中,並且逗號運算符意味着表達是不是編譯時間常數。

至少直到C++ 11沿着和relaxed the rules來到,添加括號,即case (1, 2):被允許編譯的效果。它只是不會做你期望的。

這在多個案件中部分回答開關:

怎麼會這樣?其他問題和答案几乎完全是關於C#,而不是關於C++。

我想知道爲什麼不正確的形式編譯沒有錯誤 或事件警告(至少在Borland C++編譯器)。

因爲編譯器太老。最好換個新的。

+1

有人應該向Borland發佈錯誤報告... – Walter

+0

@Walter:你爲什麼不自願? :) –

3

我的猜測是,在第一種情況下,編譯器評估逗號運營商以導致碼如下執行:

switch(variable) 
{ 
    case 2: 
    return 1; 
    case 4: 
    return 2; 
    default: 
    return 3; 
} 

從以上,可以看出爲什麼值3被返回以用於輸入我建議你閱讀一下逗號操作符。與它有關的SO有一些優秀的線索。

+0

當我發佈時沒有看到你的答案。因爲我們的答案几乎完全相同,所以我覺得自己有義務上網:) –

+0

@MadPhysicist:我很欣賞這種姿態。在公共論壇上有禮貌的人越來越少見。儘管如此,我還是回覆了這種感覺,就像你一樣,你應該得到一個滿意的答卷。 :) – therainmaker

+0

爲什麼投票人呢? – therainmaker

1

做一些實驗。

#include <stdio.h> 

int test(int variable) { 
    switch (variable) 
    { 
    case 1, 2: 
     return 1; 
    case 3, 4: 
     return 2; 
    default: 
     return 3; 
    } 
} 

int main(void) { 
    int i; 

    for (i = 1; i <= 5; i++) 
    { 
    printf("%d -> %d\n", i, test(i)); 
    } 
    return 0; 
} 

在Borland C++ 5.5.1爲Win32編譯,則輸出是

1 -> 3 
2 -> 1 
3 -> 3 
4 -> 2 
5 -> 3 

它表明1, 2被解釋爲23, 4被解釋爲4

+0

我們如何才能知道,即使只是閱讀代碼,而無需編寫測試工具? –

3

a, b在C和C++中都是有效的表達式。這意味着「評估a,丟棄它,評估b」。表達式的值是b。所以,你的原switch具有以下含義:

variable = 1; 
switch(variable) 
{ 
    case 2: 
    return 1; 
    case 4: 
    return 2; 
    default: 
    return 3; 
} 

更多關於逗號操作符,你可以閱讀Wikipedia article

2

形式爲a, b的表達式的值爲b。這就是逗號運算符的工作原理。

表面上然後case 1, 2:相當於case 2:,以此類推。

然而,一個標籤的情況下必須是一個常量積分表達式,和1, 2常量表達式,因爲它包含逗號運算符(該C++語法決定了一個常量表達式不能包含逗號操作符)。因此你的編譯器應該發出一個錯誤。

你會經常看到case 1: case 2:其中,由於switch跟進行爲,將允許下面這條線同時爲1和2的情況下運行的語句。

0

在C或C++,逗號表達式具有以下規則:

  1. 從左至右操作。
  2. 逗號表達式的值是最後一個表達式的值。

因此,代碼case 1,2:等於case 2:由於是逗號表達式有你可能要檢查的2

+0

我真的很驚訝,許多人甚至沒有嘗試在回答之前編譯代碼。 –

相關問題