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. 数据结构C++实现-第一章 绪论

    1.1 计算机与算法 1.1.3 起泡排序 void bubbleSort(int a[], int n) { for(bool sorted=false; !sorted; --n) { sorte ...

  2. 剑指offer26:将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

    1 题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 2 思路和方法 在二叉搜索树中,每个结点都有两个分别指向其左.右子树的 ...

  3. pt-table-checksum和pt-table-sync使用

    pt-table-checksum和pt-table-sync使用 数据库版本:5.6.25 pt工具版本:2.2.14 主从关系一:不同机器同一端口 10.10.228.163:4306(rescs ...

  4. MyBatis学习存档(4)——进行CRUD操作

    使用MyBatis进行数据库的CRUD操作有2种方式:一种如之前所说的接口+xml,而另一种是通过对接口上的方法加注解(@Select @Insert @Delete @Update) 但是通常情况下 ...

  5. tesseract ocr .Net demo

    环境vs 2019 .Net 4.8 新建一个wpf工程,拖放上一个button一个textbox nuget下载tesseract,版本信息如图所示 MainWindow.xaml.cs文件代码如下 ...

  6. AlertManager 部署及使用

    熟悉了 Grafana 的报警功能,但是 Grafana 的报警功能目前还比较弱,只支持 Graph 的图表的报警.今天来给大家介绍一个功能更加强大的报警工具:AlertManager. 简介 之前我 ...

  7. [NOIP10.4模拟赛]3.z题解--思维

    题目链接: 咕咕 闲扯: 哈哈这道T3考场上又敲了5个namespace,300+行,有了前车之鉴还对拍过,本以为子任务分稳了 结果只有30分哈哈,明明用极限数据对拍过不知怎么回事最后数据又是读不全, ...

  8. Oracle数据库(实例)删除用户和表空间

    删除用户drop user IMPLOCAL cascade; 删除表空间drop tablespace IMPLOCAL including contents and datafiles casca ...

  9. DX使用随记--其他

    1.  百分号显示格式 百分号:{0:P}表示显示为百分号模式.如数据源中为0.5.表示出来为50%

  10. go语言入门(10)并发编程

    1,概述 1.1并发和并行 并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行. 并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行, ...