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. 【AtCoder】AGC004

    AGC004 A - Divide a Cuboid 看哪一维是偶数,答案是0,否则是三个数两两组合相乘中最小的那个 #include <bits/stdc++.h> #define fi ...

  2. opencv实现人脸识别(四) 人脸识别模块

    到这一步就是进行人脸识别了. 流程图: 代码: import cv2 def recognize(cam): recognizer = cv2.face.LBPHFaceRecognizer_crea ...

  3. python+socket实现网络信息交互及文件传输

    Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket又称"套接字",应用程序通常通过"套接字" ...

  4. S03_CH02_AXI_DMA PL发送数据到PS

    S03_CH02_AXI_DMA PL发送数据到PS 1.1概述 本课程的设计原理分析. 本课程循序渐进,承接<S03_CH01_AXI_DMA_LOOP 环路测试>这一课程,在DATA ...

  5. WMIC命令的利用技巧

    WMIC扩展WMI(Windows Management Instrumentation,Windows管理工具),提供了从命令行接口和批命令脚本执行系统管理的支持.在WMIC出现之前,如果要管理WM ...

  6. mvc控制器返回操作结果封装

    实体类 public class AjaxResult { /// <summary> /// 获取 Ajax操作结果类型 /// </summary> public Resu ...

  7. scala中ClassOf、asInstenceOf、isInstanceOf三个预定义方法分析

    classOf.isInstanceOf.asInstanceOf三个预定义方法分析 Scala的三个预定义(predefined)方法,我们经常用到:它们用来感觉很简单, 但是里面还是隐藏了一些细节 ...

  8. vue-添加全局扩展方法

    1.添加全局方法或者属性,如: vue-custom-element 2.添加全局资源:指令/过滤器/过渡等,如 vue-touch 3.通过全局 mixin 方法添加一些组件选项,如: vue-ro ...

  9. iphone SprintBoard部分私有API总结(不支持iOS8)

    本文介绍iOS SrpintBoard框架的部分私有API,具体包括: 获取ios上当前正在运行的所有App的bundle id(不管当前程序是在前台还是后台都可以) 获取ios上当前前台运行的App ...

  10. sys和system用户的权限区别

    http://blog.sina.com.cn/s/blog_869b0f460100uckp.html Oracle sys和system用户.sysdba 和sysoper系统权限.sysdba和 ...