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

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

切換if-etc語句的優點

切換if-etc語句的優點

C++
米脂 2019-07-06 15:56:38
切換if-etc語句的優點使用switch語句與使用if發言30unsigned枚舉,其中大約10個具有預期的操作(目前是相同的操作)。業績和空間需要考慮,但并不重要。我已經抽象了片段,所以不要因為命名約定而討厭我。switch聲明:// numError is an error enumeration type, with 0 being the non-error case // fire_special_event() is a stub method for the shared processingswitch (numError){     case ERROR_01 :  // intentional fall-through   case ERROR_07 :  // intentional fall-through   case ERROR_0A :  // intentional fall-through   case ERROR_10 :  // intentional fall-through   case ERROR_15 :  // intentional fall-through   case ERROR_16 :  // intentional fall-through   case ERROR_20 :   {      fire_special_event();   }   break;   default:   {     // error codes that require no additional action   }   break;       }if聲明:if ((ERROR_01 == numError)  ||     (ERROR_07 == numError)  ||     (ERROR_0A == numError)  ||      (ERROR_10 == numError)  ||     (ERROR_15 == numError)  ||     (ERROR_16 == numError)  ||     (ERROR_20 == numError)){   fire_special_event();}
查看完整描述

3 回答

?
互換的青春

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

用開關。

在最壞的情況下,編譯器將生成與if-etc鏈相同的代碼,因此不會丟失任何東西。如果有疑問,首先將最常見的情況放在Switch語句中。

在最好的情況下,優化器可能會找到一種更好的方法來生成代碼。編譯器通常做的事情是構建一個二進制決策樹(在平均情況下保存、比較和跳轉),或者簡單地構建一個跳轉表(根本不需要比較)。


查看完整回答
反對 回復 2019-07-06
?
慕斯王

TA貢獻1864條經驗 獲得超2個贊

對于您在示例中提供的特殊情況,最清晰的代碼可能是:

if (RequiresSpecialEvent(numError))
    fire_special_event();

顯然,這只是將問題轉移到代碼的另一個區域,但是現在您有機會重用此測試。對于如何解決這個問題,您還有更多的選擇。您可以使用std:set,例如:

bool RequiresSpecialEvent(int numError){
    return specialSet.find(numError) != specialSet.end();}

我并不是說這是RequiresSpecialEvent的最佳實現,只是說這是一個選項。您仍然可以使用開關或if-Else鏈,或者查找表,或者對值進行一些位操作,諸如此類。決策過程越模糊,就越能從孤立的函數中獲得更多的價值。


查看完整回答
反對 回復 2019-07-06
?
溫溫醬

TA貢獻1752條經驗 獲得超4個贊

開關更快。

只需嘗試循環中的30個不同值,并將其與使用開關的相同代碼進行比較,以查看開關的速度有多快。

現在,開關有一個真正的問題:開關必須在編譯時知道每種情況下的值。這意味著以下代碼:

// WON'T COMPILEextern const int MY_VALUE ;void doSomething(const int p_iValue){
    switch(p_iValue)
    {
       case MY_VALUE : /* do something */ ; break ;
       default : /* do something else */ ; break ;
    }}

不會編譯。

大多數人會使用定義(!),而其他人則會在同一個編譯單元中聲明和定義常量變量。例如:

// WILL COMPILEconst int MY_VALUE = 25 ;void doSomething(const int p_iValue){
    switch(p_iValue)
    {
       case MY_VALUE : /* do something */ ; break ;
       default : /* do something else */ ; break ;
    }}

因此,最終,開發人員必須在“速度+清晰度”和“代碼耦合”之間進行選擇。

(不是說開關不能寫成像地獄一樣令人困惑.我目前看到的大多數開關都屬于這個“令人困惑”的類別.但這是另一個故事.)


將常量定義為頭文件中的枚舉是處理此問題的另一種方法“。

它當然是的。

外部類型的目的是將值與源分離。將此值定義為宏、作為簡單的Constint聲明,甚至定義為枚舉具有內聯值的副作用。因此,如果定義、枚舉值或Constint值發生變化,則需要重新編譯。Extern聲明意味著在發生值更改時不需要重新編譯,但另一方面,則不可能使用開關。結論是使用開關將增加交換機代碼與用作情況的變量之間的耦合。..當它是好的,然后使用開關。當它不是的時候,那就不足為奇了。


查看完整回答
反對 回復 2019-07-06
  • 3 回答
  • 0 關注
  • 422 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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