首页 > Switch语句比起if else语句有哪些优势?

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

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


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


在大多数情况下,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;

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


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

在我看来,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);
  ...
}

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

【热门文章】
【热门文章】