654-C语言的选择结构语句

顺序结构:一行一行往下写

选择结构(if else)

第一种写法:
expr为true的话,进入if语句
在这里插入图片描述

第二种写法:
expr为true的话,进入if语句中执行,如果expr为false的话,进入else语句中执行
要么进入if语句,要么进入else语句,是不可能同时进去的。
在这里插入图片描述
第三种写法:
expr1为true的话,进入if语句中执行
expr2为true的话,进入else if语句中执行
如果前两个都是false的话,进入else语句中执行
从上到下依次判断,哪个表达式为true就进入哪个
如果expr1和expr2都为true的话,从上到下判断,只进入第一个为true的if语句中,其他分枝就不判断了,直接跳出了。
在这里插入图片描述

if else的代码示例

写代码:
在这里插入图片描述

题目1:
在这里插入图片描述
思路:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题目2:
在这里插入图片描述
和字符比较或者和整数比较都可以,因为字符就是整数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
题目3:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果还有其他的要求,就增加else if,else if的个数可以好多个,实际上最好不要超过3个,转成表驱动
在这里插入图片描述
在这里插入图片描述
如果我们什么都不输入,直接回车, 也可以!
在这里插入图片描述

判断输入的年份是不是闰年

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

选择结构(switch case)

在这里插入图片描述

在这里插入图片描述
expr结果必须是整数
因为它要拿这个整数的结果和v1比较,如果比对成功,就进入,执行完,break直接跳出整个switch了。
如果这个结果和v1,v2,v3都不匹配的话,就执行default的语句,执行完,break直接跳出这个switch
我们可以这么写:
在这里插入图片描述
也可以写成字符,因为字符就是整数
在这里插入图片描述
但是不可以写成字符串!!!:
在这里插入图片描述
也不可以写成浮点数:况且浮点数也不能直接比较大小的
在这里插入图片描述
在这里插入图片描述
下面这么写,会把case1,case2,case3的语句都执行了,然后才break跳出整个switch语句,因为前面的case后面没有加break!!!:
在这里插入图片描述
在这里插入图片描述
代码应用:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

统计年份和指定日期的总天数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们看下面这题要求:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

两种选择结构汇编指令比较

一个函数里如果使用if else的分枝或者switch分枝超过3次以上,我们就要转成相应的表驱动。

应用场景的区别:
switch只能做等值比较,有限集合的整数的等值比较,适用于菜单,月份

在这里插入图片描述
效率差别?
在这里插入图片描述

在这里插入图片描述
我们转到if else if的反汇编看看
在这里插入图片描述
在这里插入图片描述
我们从头开始分析
在这里插入图片描述
拿a和10(0Ah)比较,比较的结果放入cmp中
如果不相等的话,执行jne跳转,往04C43B3h跳转
如果相等的话,就不跳转了,就进入{}了,执行b++的3行指令
在这里插入图片描述
如果执行完了b++的三行指令,就跳转jmp,跳转到04C43DFh
在这里插入图片描述
04C43DFh在哪?在switch语句的头
在这里插入图片描述
也就是说,10==a了,进这个if语句,执行完b++后,直接无条件jump跳出整个if else语句了
这是符号我们的预期的
如果10!=a,是跳转到04C43B3h
04C43B3h在哪里?
在下一个分枝
在这里插入图片描述
拿20(14h)和a比较,结果的情况和刚才所述一样,以此类推下去。

在这里插入图片描述
在这里插入图片描述
我们看看switch的反汇编
在这里插入图片描述
我们从头开始看
在这里插入图片描述
switch在进行比较的时候,先把a的值放到寄存器,又把寄存器的值放到栈上的临时量,然后拿这个临时量的值和10比较,如果和10相等,执行je,跳转,就跳转到04C4405h,在这里插入图片描述
如果和10不相等,也就是je在这里不跳转,继续和14h,也就是20比较了,如果相等,就跳转到04C4410h在这里插入图片描述
如果继续不相等的话,就和1Eh,也就是30,比较,以此类推。
在这里插入图片描述
如果所有的都不相等,无条件跳转到04C4426h
在这里插入图片描述
break执行的是jmp。在这里插入图片描述
直接跳出整个switch

也就是说,在进行元素等值比较的时候,if else和switch差别不大。

唯一的区别是:if else如果比较相等的话,不用做指令跳转,直接执行++的指令了。
而switch比较如果相等的话,要做指令的跳转,跳转到指定地址的指令上去执行。
如果比较不相等的话,if else 是跳转到下一个分枝的第一个指令的地址上继续判断。而在switch里面,如果不相等的话,不用做指令的跳转,进行向下判断,因为它把所有的case的判断都放在前面switch这里进行统一判断了。

从汇编上看,它们的差别不是很大,if else的每个分枝都要做一个cmp比较,有多少个分枝,就有多少个cmp。在switch中,case里面也是要拿当前switch里面的值和所有的case进行比较。有多少个case,就有多少个cmp

在这里插入图片描述
如果分枝过多的话,做的cmp和指令跳转的次数就非常多,这是比较慢的操作,而且是从上到下一个一个的比较,比较花费的时间复杂度是O(n)
如果我们转成哈希表的表驱动的方式进行分枝选择的话,哪怕这个分枝有1万个,时间复杂度是O(1),这是由哈希表决定的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值