为什么说switch比if快
C++的switch语法
在C++中,switch只接受整型常量作为分支的值:
switch (expr) {
case integral-constant :
\\...
break;
case integral-constant :
\\...
break;
default :
\\...
break;
}
这里有几个需要注意的细节:
- 最好将default分支写出来,即使什么也不做
- 若分支没有写break语句,那么最好注释为什么这么做
- 若要在switch内定义变量需要创建一个作用域{},否则从语法上就可以跳过变量的初始化而直接使用变量,这样是不合理的所以编译会直接报错
switch的实现原理
switch的实现利用了跳转表这一数据结构,其实就是一个保存各个分支代码入口地址的数组。与一连串的if/else相比,跳转表的优点就是确定分支代码的时间和分支数量无关,是一个常数。
编译器会根据switch的分支数量以及分支对应的值的稀疏程度来决定如何翻译代码。当分支数量较多且值相对集中的时候就会采用跳转表来实现。
//原版C++代码
int ans = 0;
switch (n) {
case 100 :
ans = 0;
break;
case 102 :
ans = 2;
//fall through
case 103 :
ans = 3;
break;
case 104 :
//fall through
case 106 :
ans = 6;
break;
default :
ans = 0;
}
return ans;
//翻译为跳转表的C++代码
//跳转表
static void *jt[7] = {
&&loc_A, &&loc_def, &&loc_B,
&&loc_C, &&loc_D, &&loc_def,
&&loc_D
};
//对分支对应的值做简单的坐标变换
unsigned index = n - 100;
int ans = 0;
//default分支
if (index > 6) {
goto def;
}
//进行分支跳转
goto &jt[index];
//case 100
loc_A :
ans = 0;
goto done;
//case 102
loc_B :
ans = 2;
//fall through
loc_C :
ans = 3;
goto done;
//case 104 106
loc_D :
ans = 6;
goto done;
loc_def :
ans = 0;
done :
return ans;
- 素材来自«深入理解计算机系统»