切换if-etc语句的优点

切换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();}


米脂
浏览 385回答 3
3回答

互换的青春

用开关。在最坏的情况下,编译器将生成与if-etc链相同的代码,因此不会丢失任何东西。如果有疑问,首先将最常见的情况放在Switch语句中。在最好的情况下,优化器可能会找到一种更好的方法来生成代码。编译器通常做的事情是构建一个二进制决策树(在平均情况下保存、比较和跳转),或者简单地构建一个跳转表(根本不需要比较)。

慕斯王

对于您在示例中提供的特殊情况,最清晰的代码可能是:if (RequiresSpecialEvent(numError))     fire_special_event();显然,这只是将问题转移到代码的另一个区域,但是现在您有机会重用此测试。对于如何解决这个问题,您还有更多的选择。您可以使用std:set,例如:bool RequiresSpecialEvent(int numError){     return specialSet.find(numError) != specialSet.end();}我并不是说这是RequiresSpecialEvent的最佳实现,只是说这是一个选项。您仍然可以使用开关或if-Else链,或者查找表,或者对值进行一些位操作,诸如此类。决策过程越模糊,就越能从孤立的函数中获得更多的价值。

温温酱

开关是更快。只需尝试循环中的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声明意味着在发生值更改时不需要重新编译,但另一方面,则不可能使用开关。结论是使用开关将增加交换机代码与用作情况的变量之间的耦合。..当它是好的,然后使用开关。当它不是的时候,那就不足为奇了。
打开App,查看更多内容
随时随地看视频慕课网APP