| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 【汇编 C】switch为什么高效率?分支语句if else与switch -> 正文阅读 |
|
[C++知识库]【汇编 C】switch为什么高效率?分支语句if else与switch |
目录 前言? ? ? ? 本文章使用到的工具是vs2010,建议使用VC++6,操作都一样。 什么是分支语句?????????分支语句即进行一个选择,如果出现情况A则进行相应的操作;如果出现情况B则进行相应的操作,等等。 if else分支语句? ? ? ? 我们也知道if是如果的意思,那么可以根据意思理解,比如: ? ? ? ? if(love == true)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 如果love是真不是假 ? ? ? ? ? ? ? ? printf("这是真爱。\n");? ? ? ? ? ? // 那么就输出这是真爱 ? ? ? ? else? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 否则(如果love不是真,是假的) ? ? ? ? ? ? ? ? printf("假的。\n");? ? ? ? ? ? ? ? ? ?// 那么就输出假的 ? ? ? ? if else的几种写法? ? ? ? 1)if(条件) 语句; ? ? ? ? 2)if(条件) { 语句;...} ? ? ? ? 3)if(条件1)?语句1; ? ? ? ? ? ? ? else? 语句2; ? ? ? ? 4)if(条件1) { 语句1;...} ? ? ? ? ? ? ? else { 语句2;...} ? ? ? ? 5)if(条件1) 语句1; ? ? ? ? ? ? ? else if(条件2) 语句2; ? ? ? ? ? ? ? else 语句3 ? ? ? ? 6)if(条件1) { 语句1;...} ? ? ? ? ? ? ? else if(条件2) { 语句2;...} ? ? ? ? ? ? ? else { 语句3;...} ? ? ? ? 注意注意!!! ? ? ? ? 上面的写法并不是所有的,也并不是!只要if写大括号、else if就必须写大括号的!!!什么时候写大括号,什么时候不写呢?只有当语句只有一条的时候才可以省略不写大括号,如果一个if条件成立之后需要做很多语句,那就必须带大括号。 ? ? ? ? 注意事项? ? ? ? 1、可以只写if语句不写else语句,但是不能只写else语句。 ? ? ? ? 2、else if可写可不写,如果写就必须有if语句。 ? ? ? ? 底层刨析? ? ? ? 测试代码:
? ? ? ? 首先我们来看运行结果: ? ? ? ? 没问题。 ? ? ? ? Ctrl+alt+f7重新生成,?F5运行,ALT+8调出反汇编,如下: ? ? ? ? 我们先来看if(x==1) printf("x=1\n");对应的汇编:? ? ? ? ? cmp dword ptr [x],1: ? ? ? ? ? ? ? ? 将局部变量x中的值与1进行比较。 ? ? ? ? jne main+46h(5813d6h): ? ? ? ? ? ? ? ? 如果前者(x)不等于后者(1)就跳转到5813d6这个地址,可以发现这个地址是else if,如果等于的话就继续往下执行 ? ? ? ? mov esi,esp: ? ? ? ? ? ? ? ? 备份 ? ? ? ? push offset...: ? ? ? ? ? ? ? ? 传递给printf函数参数。 ? ? ? ? call dword ptr[__imp__printf()]: ? ? ? ? ? ? ? ? 调用printf函数? ? ? ? ? add esp,4: ? ? ? ? ? ? ? ? 一个参数,平栈加4 ? ? ? ? cmp esi,esp: ? ? ? ? ? ? ? ? 比较二者的值 ? ? ? ? call @ILT+300: ? ? ? ? ? ? ? ? 如果两者的值不相等,这个函数会报错,相等不会。 ? ? ? ? jmp main+7Ch(54180Ch): ? ? ? ? ? ? ? ? 跳转到54180C这个地址。 ? ? ? ? 上面的指令是整个if printf的流程。先判断,如果不相等就跳转到else if,如果相等就执行输出,并且到最后输出完了会跳转到整个if elseif else分支之外。 ? ? ? ? else if(x>1) printf("x>1");? ? ? ? ? else? ? ? ? ? 以上便是if else的底层汇编,可以发现如果条件是'>'那么底层就会判断是否小于等于,以此类推,大家可以实验下。? switch分支语句? ? ? ? switch语句的格式? ? ? ? switch(表达式) ? ? ? ? { ? ? ? ? ? ? ? ? case 常量表达式1: ? ? ? ? ? ? ? ? ? ? ? ? 语句; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case 常量表达式2: ? ? ? ? ? ? ? ? ? ? ? ? 语句; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ... ? ? ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? ? ? ? ? 语句; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? } ? ? ? ? 注意事项? ? ? ? 1、switch后边表达式的结果不能是浮点数! ? ? ? ? 2、case后的值不能一样,并且必须是常量,一般对应switch后面表达式的各种结果 ? ? ? ? 3、default放在最后的时候可以不用写break;但是放在前面必须写 ? ? ? ? 4、default不一定写在最后面,如果写在前面必须带break; ? ? ? ? default与break的功能? ? ? ? default就是默认的意思,可以看到,我们switch语句中有很多case,case就相当于if(x == ?)这样的。default就相当于else语句,当case中的表达式都不成立就会执行default,如下:
? ? ? ? 结果: ? ?? ? ? ? ? break是什么?? ? ? ? ? 如果循环语句中假如break;那么他会跳出循环,那么当我们条件分支语句加上break;他也是会跳出的。 ? ? ? ? 为什么最后一行的不需要加break? ? ? ? ? 因为最后一行的没有必要加,他再执行一步,分支语句就会退出了,所以没必要。 ? ? ? ? 例如(不加的情况):
? ? ? ? 结果: ? ? ? ? 我们得到两点结论: ? ? ? ? 1、如果上面的条件成立了,但是没有写break,那么执行了语句之后还会继续往下执行不会退出分支语句 ? ? ? ? 2、当上面的条件成立了之后如果没有写break,那么继续往下执行的时候就不会再判断case了,只有等到break;才会退出,或者一直执行完。? ? ? ? ? 底层刨析? ? ? ? 代码:
? ? ? ? __asm处断点、CTRL+ALT+F7重新生成、F5调试、ALT+8反汇编: ? ? ? ? 这里就不一步一步分析了。 ? ? ? ? ? ? 可以看到switch语句也是判断,如果等于就跳转到对应的位置,和if else语句貌似是一样的,那么为什么说switch语句高效呢?? switch语句为什么高效?????????? ? ? ? 首先我们需要了解一下switch语句的应用场景,我们知道游戏中一般都会有快捷键,这些快捷键的底层一般都是switch语句设计的,如果有快捷键,基本上不会只有一个快捷键。所以,如果仅仅是一两个条件,是根本看不出switch语句与if else的差距的。 ? ? ? ? 我这里使用的是vs2010,在这个编译器中,当条件达到四个时(不含default),switch语句就会开始高效,他与if else的差距也能轻易看出来了。(并不是所有场景都是switch条件达到四个才开始高效,一般这与编译器优化有关)。 ? ? ? ? 实例测试? ? ? ? 示例代码if else四条件:
? ? ? ? ctrl+alt+f7重新生成、F5调试、ALT+8反汇编: ? ? ? ? 可以看到if else语句条件多与少是没有区别的。 ? ? ? ? 示例代码switch:
?????????ctrl+alt+f7重新生成、F5调试、ALT+8反汇编: ? ? ? ? 直接看图: ? ? ? ? 结论?? ? ? ? 当switch语句的条件超过一定个数时,底层会生成一张表(就是某个地址*edx+4)我们查看所谓的某个地址就会看到这张表,如下: ? ? ? ? 这张表是通过算法计算生成的,里边存放着所有case的成立之后跳转的地址,所以我们不需要再判断一次跳转一次,判断一次跳转一次......我们直接可以通过这张表,跳转到对应的位置,这也就是switch语句的精妙之处。当分支特别多的时候switch语句与if else的差距就会越来越大。? ? ? ? ? 注意事项? ? ? ? 这里大家可以通过demo程序测试一下,如果是case 1:、case 3:、case 7:这样分隔开的话,底层会是什么样的呢?如果是case 1:、case 10:、case 100:这样差距特别大的,那么switch底层又会怎么办呢?跟谁比?减多少? ? ? ? ? 这样的问题很简单,写个程序测试一下一眼就能得出结论,所以我就不写了。 总结? ? ? ? 无论是if else或是switch都各有应用场景,如果你觉得switch高效,那么以后什么地方都用switch吗?不能这样,因为很多地方不需要判断那么多次,并且switch不能像if else那么灵活。 ? 结语? ? ? ? 文章到这里就结束了,感谢大家观看!另外如果有错,还请一定指出;如果有听不懂,一定要问。? ? ? ? ? 封面: ? |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 17:33:57- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |