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. Solr 8.2 使用指南

    1 Solr简介 1.1 Solr是什么 Solr是一个基于全文检索的企业级应用服务器.可以输入一段文字,通过分词检索数据.它是单独的服务,部署在 tomcat. 1.2 为什么需要Solr 问题:我 ...

  2. 二叉查找树 & B(B-)树 & B+树 & B*树

    一 二叉查找树 1 特点 (1)所有非叶子结点至多拥有两个子节点, left和right (2)一个结点存储一个关键字 (3)非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树 2 ...

  3. c# dateTime格式转换为Unix时间戳工具类

    using System; using System.Collections.Generic; using System.Text; namespace TJCFinanceWriteOff.BizL ...

  4. Photon Server 实现注册与登录(二) --- 服务端代码整理

    一.有的代码前端和后端都会用到.比如一些请求的Code.使用需要新建项目存放公共代码. 新建项目Common存放公共代码: EventCode :存放服务端自动发送信息给客户端的code Operat ...

  5. js 怎样判断用户是否在浏览当前页面

    有些时候我们需要在项目中判断用户是否在浏览当前页面,或者当前页面是否处于激活状态.然后再进行相关的操作.浏览器中可通过window对象的onblur.onfocus判断,或者document的hidd ...

  6. Sql语句知识大全

    1.经典SQL语句大全(绝对的经典) 2. 3. 4.一.基础 1.1.说明:创建数据库 2.CREATE DATABASE database-name 3.2.说明:删除数据库 4.drop dat ...

  7. 【原创】大叔经验分享(76)confluence和jira配置

    一 下载 confluence https://product-downloads.atlassian.com/software/confluence/downloads/atlassian-conf ...

  8. 前端性能优化-Vue代码层面

    1.v-if 和 v-show 区分使用场景 v-if 是 真正 的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建:也是惰性的:如果在初始渲染时条件为假,则什么也不做 ...

  9. luogu2858奶牛零食题解--区间DP

    题目链接 https://www.luogu.org/problemnew/show/P2858 一句话题意: https://cn.vjudge.net/problem/POJ-3186#autho ...

  10. centos 中 Java环境变量配置

    一.安装java 1.搜索java包 yum search java 2.安装java包 -openjdk.x86_64 3.查看java安装目录 whereis java #找到Java目录 一般在 ...