2013-05-11 49 views
0

以下代碼是我正在閱讀的解釋器的一部分。我試圖找出爲什麼使用這個而不是簡單的c >= '0' && c <= '9'選擇很多情況,而不是c> ='0'&& c <='9'到0-9數字檢查

switch(ch) { 
    //... 
    case '0': case '1': case '2': 
    case '3': case '4': case '5': 
    case '6': case '7': case '8': 
    case '9': 
    //etc 
    break; 
    //more cases 
} 

我也很好奇爲什麼選擇使用開關。它是如何作爲解釋器的代碼的,我相信作者有背景C知道。這是最快的比c >= '0' && c <= '9'條件還是這種方式讓編譯器做一些優化?它是使用gcc編譯的

+4

沒有看到什麼「更多的情況下」都不能回答這個問題。例如,它可能是交換機覆蓋了對該語言有意義的*整個*字符集,並且它實際上是用一個跳轉表進行N路選擇 - 這就是'switch'是真的很擅長。或者可能有人不知道他們可以安全地做'c'='0'&& c <='9''。或者還有第三件事。沒有辦法從你給我們的東西中分辨出來。 – zwol 2013-05-11 00:04:28

+0

在記分員中使用'switch'是相當普遍的做法 - 部分原因是'switch'總是使用跳轉表來提高速度。即使是現在,'switch'也不能使用跳轉表,但只是因爲有一個更好的選項(比如硬編碼的二進制搜索)。編譯器很難發現if/elseif/else條件可以以相同的方式實現,因爲條件更加靈活,甚至可能產生副作用,儘管編譯器始終變得更加智能。 – Steve314 2013-05-11 03:15:20

回答

3

您不能在交換機case中使用條件。如果你想使用c >= '0' && c <= '9',那麼你必須使用一個if語句,那麼它可能使檢查等情況下難以,例如:

if (c >= '0' && c <= '9') { 
    // ... 
} else if (c == 'a') { 
    // ... 
} else if (c == 'b') { 
    // ... 
} else if (c == 'c') { 
    // ... 
} // more cases 

可能不會好於

switch(ch) { 
    //... 
    case '0': case '1': case '2': 
    case '3': case '4': case '5': 
    case '6': case '7': case '8': 
    case '9': 
    //etc 
    break; 
    case 'a': //... 
    case 'b': //... 
    case 'c': //... 
    //etc 
} 
2

專門爲數字只有,這保證產生與等效的if相同的結果。

但是,根據「更多案例」部分,使用switch編寫代碼時可能更易於閱讀代碼。例如,如果「更多的情況下,」要趕上所有小寫字母這將是理論上錯寫這樣的測試:

if (c >= 'a' || c <= 'z') 

所以你必須把它寫這樣的:

if (c == 'a' || c == 'b' || ...) 

在這種情況下,使用switchif/elseif容易得多。

+1

擴展到「理論上錯誤」 - 一個原因可能是[EBCDIC](https://en.wikipedia。org/wiki/Extended_Binary_Coded_Decimal_Interchange_Code),更常見的原因是(取決於語言和字符集)可能需要考慮更多的小寫字母。也就是說,你必須知道那些字母是用「if」還是「switch」 - 這是使用'islower'和family的情況。 – Steve314 2013-05-11 03:40:42

2

也許

if(isdigit(ch)){ 
    //etc 
} else { 
    //more cases 
} 
1

正如@Zack提到的,它取決於什麼是「更多的情況下」是一個偉大的交易。當交換機中有很多情況時,許多編譯器會生成條件指令和跳轉表的優化組合。這不一定只是一個可讀性問題。

0

如果使用GCCClang你也可以這樣寫:

switch(ch) { 
    //... 
    case '0' ... '9': 
    //stuff 
    break; 
    //more cases 
}