1.关于switch语句
如果if语句中表达式是判断是否等于一个常量时,可以用switch语句来代替
if(表达式 == 常量1)                       
{                             
    //...代码                          
}                           
else if(表达式 == 常量2)                          
{                        
    //...代码                      
}                           
else if(表达式 == 常量3)        
{                           
    //...代码               
}                               
else                          
{                          
    //...代码                       
}                           
相当于:
switch(表达式)        
{        
    case 常量表达式1:    
        语句;
        break;
    case 常量表达式2:    
        语句;
        break;
    case 常量表达式3:    
        语句;
        break;
    case 常量表达式4:    
        语句;
        break;
    default:    
        语句;
        break;
}    
也就是说:
    switch语句 是if语句的简写
 
switch要求:            
    1、case后面必须是常量表达式            
    2、case后常量表达式的值不能一样            
    3、switch后面表达式必须为整数
 
如果不要break,将在满足条件的表达式处开始一直向下执行,直到见到break为止;
当条件都不满足时执行default后的语句;
 
2.反汇编分析
1)当分支较少时switch和if差别多,都是每个分支都判断,然后执行相关语句;
void fun()    
{   
    int i = 2;
    switch(i){
    case 1:
        printf("1");
        break;
    case 2:
        printf("2");
        break;
    case 3:
        printf("3");
        break;
    default:
        printf("4");
        break;
    }
}
 
int main(int argc, char* argv[])
{    
    fun();
    getchar();
    return 0;
}
 
2)当有多个分支时switch的性能优于if
不需要每个分支都判断;
void fun()    
{   
    int i = 2;
    switch(i){
    case 1:
        printf("1");
        break;
    case 2:
        printf("2");
        break;
    case 3:
        printf("3");
        break;
    case 4:
        printf("4");
        break;
    case 5:
        printf("5");
        break;
    case 6:
        printf("6");
        break;
    default:
        printf("7");
        break;
    }
}
 
 
int main(int argc, char* argv[])
{    
    fun();
    getchar();
    return 0;
}
反汇编分析:
跳转到case2处:
 
结果:
    switch语句的强悍之处在于,它会在哪内存中生成一张表,存储每一条分支语句的地址;
当把分支条件传进来时,可以通过表达式直接定位到真正要跳转到的分支语句地址;
 
如果把case的常量交换顺序,依然可以正确定位到对应的分支;
 
3)规律
1】分支少于一定数量时,用switch没有意义;
因为编译器此时不会为switch不生成大表,和if一样需要每个参数都判断;
2】case后面的常量可以是无序的,并不影响大表的生成;
3】为了生成大表,通常会减去最小值的case常量,以此来确定大表的地址;
例如:如果最小的分支常量为1,则有sub ecx,1;如果最小分支常量是301,则sub ecx,301;以此类推;
4】如果常量连续,但中间缺少少数几个常量,大表会在缺少的地方放default的地址;
5】如果常量连续,但中间缺少的常量达到一定数量,编译器为了节省内存,会采取创建小表的策略;
    小表占一个字节的空间;因此如果间隔超过255个数将无法生成小表;
6】如果分支常量毫无规律差值过大、编译器为了节省内存将不会生成大表和小表;
 
4)编译器创建小表时的反汇编
switch语句代码:连续的分支常量,但中间缺少了一定数量的常量;
 
反汇编:
内存:
 
 
 

switch语句分析的更多相关文章

  1. 通过字节码分析java中的switch语句

    在一次做题中遇到了switch的问题,由于对switch执行顺序的不了解,在这里简单的通过字节码的方式理解一下switch执行顺序(题目如下): public class Ag{ static pub ...

  2. switch...case...语句分析(大表跟小表何时产生)

    一.switch...case...的格式 switch(表达式) { case 常量表达式1: 语句; break; case 常量表达式2: 语句; break; case 常量表达式3: 语句; ...

  3. 透过IL看C#:switch语句(转)

    透过IL看C# switch语句(上) 摘要: switch语句是 C#中常用的跳转语句,可以根据一个参数的不同取值执行不同的代码.本文介绍了当向 switch语句中传入不同类型的参数时,编译器为其生 ...

  4. switch语句

    应用条件语句可以很方便地使程序实现分支,但是出现分支比较多的时候,虽然可以用嵌套的if语句来解决,但是程序结构会显得复杂,甚至凌乱.为方便实现多情况选择,C++提供了一种switch开关语句.   一 ...

  5. switch语句的使用,非常好

    这是谭浩强课本上枚举类型的例子,但是我贴这个例子的代码不是因为枚举类型,是因为这个代码使用switch语句用得非常好,值得一贴. 题目是这样的:有红.黄.蓝.白.黑5中颜色的球若干,依次取出3个球,求 ...

  6. PROCESS_YIELD()宏和C语言的switch语句< contiki学习笔记之七>

    写在前面:  按照main()函数的代码一行一行的分析,该是看到了 etimer_process 这个位置.但是etimer_process实现里的一个宏 PROCESS_YIELD()引出了很多故事 ...

  7. 更深入一点理解switch语句及c/c++对const的处理

    首先看一到用 c 编写的程序/* -------------------- filename : ta.c --------------- */int switch_test_first( int x ...

  8. 提高java编程质量 - (五)switch语句break不能忘以及default不同位置的用法

    先看一段代码: public class Test{ public static void main(String[] args){ System.)); } } public static Stri ...

  9. 逆向随笔 - switch 语句深入分析

    switch case 语句在c语言里还是比較简单的.可是被编译出来之后,优化结果往往让人非常疑惑.全然看不懂,以下我们一次次的尝试,看看编译器究竟把switch语句变成什么样了.   ① 先上个最简 ...

随机推荐

  1. (二)springMvc 入门

    目录 配置前端控制器 servlet拦截方式 springMvc的配置文件 编写处理器类 配置自定义处理器 配置前端控制器 在 web.xml 配置 DispatcherServlet <!-- ...

  2. RSA加密,以及证书加密

    简单的加密:https://blog.csdn.net/qq_32523587/article/details/79092364 生成证书:https://blog.csdn.net/u0121916 ...

  3. LocalDate与Date转化

    // 01. java.util.Date --> java.time.LocalDateTimepublic void UDateToLocalDateTime() { java.util.D ...

  4. Servlet获取JSP中的汉字乱码问题解决方案

    1.String customerName=request.getParameter("customer_name");这样会出现乱码 解决方案很简单: String custom ...

  5. 旋转动画(RotateTransform)

    Silverlight的基础动画包括偏移.旋转.缩放.倾斜和翻转动画,这些基础动画毫无疑问是在Silverlight中使用得最多的动画效果,其使用也是非常简单的.相信看过上一篇<偏移动画(Tra ...

  6. 钉钉微应用内置浏览器js缓存清理

    html中引用的js文件加上版本号,如下: <script type="text/javascript" src="js/xxx.js?version=1.0.1& ...

  7. Java学习路径(抛光砖)

    这就是我刚刚在五孔问答中找到的Java学习路线图抛光砖价格.我个人认为,这条Java学习路线是可以的.它是2018年相对较新的Java学习路线,更符合企业就业标准. Java学习路径的第一阶段:Jav ...

  8. Centos7.7安装swoole

    系统版本:centos 7.7(查看系统版本:cat /etc/redhat-release) 执行命令安装swoole: yum update -y && yum remove ph ...

  9. 通过ABAP代码判断当前系统类型,BYD还是S4 OP还是S4 Cloud

    用工具类 CL_COS_UTILITIES IS_BYD 如果是BYD系统,这个方法的实现会硬编码返回一个true, 在其他系统里则返回false,如图: IS_SUITE 原理同上,suite系统里 ...

  10. 变种XSS:持久控制

    变种XSS:持久控制 tig3r · 2015/11/30 10:42 0x00 引言 首先声明,这不是一个新洞,看过 Homakov 文章(最后附)以及译文的人想必对这种漏洞有所了解. 但原文写的太 ...