首页  >  问答  >  正文

c++ - Switch语句比起if else语句有哪些优势?

刚学完c++,觉得switch语句除了条理清晰些,没有别的太大优势,小弟不才,还望指教。

天蓬老师天蓬老师2765 天前828

全部回复(5)我来回复

  • PHPz

    PHPz2017-04-17 11:01:17

    在大多数情况下,switch的性能不会比if else低。
    在某些特定情况下,编译器能对switch进行优化。比如说:
    1. 不按顺序比较,而是构造一个二分查找树(binary decision tree), 这样子比较的平均次数就会下降。
    2. 可以做个跳转表(jump table)这样子就不许要任何比较了。比如如下的代码。

    int main(int argc, char* argv[])
    {
    	int j = 0;
    	int n;
    	cin>>n;
    	switch(n)
    	{
    	case 1: j = 1; break;
    	case 2:	j = 2; break;
    	case 3:	j = 3; break;
    	case 4:	j = 5; break;
    	default:j = 6;
    	}
    	cout<<j<<endl;
    	return 0
    }

    其在VS2008编译器下产生的代码如下

    switch(n)
    00401011  mov         eax,dword ptr [esp] 
    00401014  dec         eax  
    00401015  cmp         eax,3 **<==这里只比较了一次,看看是否是default分支**
    00401018  ja          0040103D 
    0040101A  jmp         dword ptr [eax*4+00401064h] **<==这里直接用了一个跳转表,没有比较语句**
    	{
    	case 1: j = 1; break;
    00401021  mov         eax,1 
    00401026  jmp         00401042 
    	case 2:	j = 2; break;
    00401028  mov         eax,2 
    0040102D  jmp         00401042 
    	case 3:	j = 3; break;
    0040102F  mov         eax,3 
    00401034  jmp         00401042 
    	case 4:	j = 5; break;
    00401036  mov         eax,5 
    0040103B  jmp         00401042 
    	default:j = 6;
    0040103D  mov         eax,6 
    	}
    	cout<<j<<endl;
    00401042  mov         ecx,dword ptr ds:[0040203Ch] 
    00401048  push        ecx  
    00401049  mov         ecx,dword ptr ds:[0040204Ch] 
    0040104F  push        eax  
    00401050  call        dword ptr ds:[00402038h] 
    00401056  mov         ecx,eax 
    00401058  call        dword ptr ds:[00402040h] 
    	return 0;

    回复
    0
  • PHP中文网

    PHP中文网2017-04-17 11:01:17

    呵呵,这是一个相当有趣的问题。

    在我看来,switch的确在实质上跟if else if 完全一样的效果,不过在很多情况下,使用switch要比if else方便不少

    比如经典的值等分支,匹配一些状态常量的时候,比if else结构方便许多,不用反复写xx == yy

    switch (param) {
      case STATUS_ONE:
        ...
        break;
      case STATUS_TWO:
        ...
        break;
      default:
        ...
    }

    vs

    if (param == STATUS_ONE) {
      ...
    } else if (param == STATUS_TWO) {
      ...
    } else {
      ...
    }

    当然,switch在非值等分支的时候也不是那么没用,比如经典的打分评级,也可以这么写:

    switch (true) {
      case score < 60:
        return 'D';
      case score < 70:
        return 'C';
      ...
    }

    看上去也会相当的清晰。

    总之我认为switch是一个经常被小看的语法结构,用得好的话,会很省事。

    另外如果代码里面有很多平级的if却没有else,其实没有break的switch也是一个不错的选择,比如拼sql的时候:

    switch (true) {
      case id > 0:
        query->addWhere('id = ?', id);
      case (bool)name:
        query->addWhere('name = ?', name);
      ...
    }

    回复
    0
  • 迷茫

    迷茫2017-04-17 11:01:17

    本来就是如此,switch就是让你更清晰一点,不然到处的if else会让你烦死的。

    回复
    0
  • 巴扎黑

    巴扎黑2017-04-17 11:01:17

    上面说的很详细,switch语句在编译时编译器会提供一张跳转表,提高了查找速度。
    而多分支的if else语句,实际上是忌讳使用的,因为在底层指令的流水线中,if else语句会导致程序预判,将一种情况的指令装入流水线。一旦预判失败,就需要回退流水线。与switch相比,大规模使用if else的性能差异是比较大的,个人认为。

    回复
    0
  • 迷茫

    迷茫2017-04-17 11:01:17

    我也是经常用Switch 状态机, 倍爽~~

    回复
    0
  • 取消回复