2017-02-25 93 views
2

考慮下面包含重複情況的代碼(C語言)。編譯器這次沒有提供任何警告/錯誤。數據類型和開關大小寫語句解析

void testSwitchCase() { 
char d = 0; 
switch(d) { 
    case 'a' + 'b': 
     printf("I am case 'a' + 'b'\n"); 
     break; 
    case 'a' + 'b': 
     printf("I am case 'a' + 'b' \n"); 
     break; 
    } 
} 

但如果我改變char d = 0int d = 0,編譯器開始提高公衆對重複的情況下錯誤。

error: duplicate case value

我明白表達'a' + 'b'應評估到int但我的觀點是,應該提高重複錯誤的情況下這兩個時間。爲什麼它不?

+0

你使用什麼編譯器?你有沒有試過在兩個不同的編譯器上運行這個? – Daniel

+0

gcc 32位。 codeblocks-16.01mingw其中包括GCC/G ++編譯器。好的,讓我試試一些在線編譯器。 –

回答

6

此行爲的原因是系統上的值爲'a'+'b',在ASCII編碼的系統上爲195。這是高於127,最高char系統上的值與簽署的個字符。因此,編譯器安全地忽略了兩個case標籤。

由於值195int的範圍內,編譯器不能再忽略它,所以它必須發出重複的case錯誤。

如果更改'a'+'b''0'+'1',你97,這是一個符號字符的範圍內,你會得到重複的情況下誤差char d還有:

char d = 0; 
switch(d) { 
case '0' + '1': 
    printf("I am case 'a' + 'b'\n"); 
    break; 
case '0' + '1': 
    printf("I am case 'a' + 'b' \n"); 
    break; 
} 

Demo.

+0

是的錯過了。現在明白了。謝謝 :) –

0

重複大小寫錯誤表示您在switch語句中定義了兩個具有相同值的情況。你可能正在考慮你的代碼,「但它們都是不同的。」對你來說他們是不同的。對於編譯器來說,它們看起來很不一樣

您已經使用字符符號定義了case語句。單引號是用於字符,而不是字符串。

+3

我很確定OP知道這一切。看看他問題的最後一段。 – dasblinkenlight

+0

他想要角色。看看交換機中的表達式。而且他認爲他們都是一樣的,但是除非他將d變成一個整數,否則不會發出警告。 – Gerhardh

+0

你的誤解與switch()結構無關,全部是關於單引號「':如果你寫1,你得到一個整數值1,當你把它放在單引號'1'中時,你會得到數字1的ASCII字符的數字值(這有點不準確,請參閱下面的註釋)。該ASCII字符的數值爲0x31,即十進制中的49。現在想象一下不同。 – Siddhesh

1

時間太長併發布了7分鐘太遲:P ...

我的猜測如下: char變量不能保存'a'+'b',這會導致se溢出,即未定義的行爲。 但由於整數升級規則,'a'+'b'被提升爲int。 char d永遠不能等於這個值,編譯器完全刪除這些情況。 int d可以等於這兩種情況並且編譯器發出錯誤。