目录
前言
什么是分支语句?
if else分支语句
if else的几种写法
注意事项
底层刨析
switch分支语句
switch语句的格式
注意事项
default与break的功能
底层刨析
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语句。
底层刨析测试代码:
#include
#include
int main()
{
__asm mov eax,eax; // 无用的代码,设置断点,产生汇编
int x = 1;
if(x == 1) // 这里是判断,必须使用'==',因为'='在编程里是赋值
printf("x = 1\n");
else if (x > 1)
printf("x > 1\n");
else
printf("x < 1\n");
system("pause"); // 防止程序立即退出
return 0;
}
首先我们来看运行结果:
没问题。
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,如下:
#include
#include
int main()
{
int x = 1;
switch(x)
{
case 2: // 如果x==2
printf("x=2\n");
break;
case 3: // 如果x==3
printf("x=3\n");
break;
default: // 如果x!=2 并且 x!=3
printf("x!=2、x!=3\n");
break;
}
system("pause");
return 0;
}
结果:
break是什么?
如果循环语句中假如break;那么他会跳出循环,那么当我们条件分支语句加上break;他也是会跳出的。
为什么最后一行的不需要加break?
因为最后一行的没有必要加,他再执行一步,分支语句就会退出了,所以没必要。
例如(不加的情况):
#include
#include
int main()
{
int x = 1;
switch(x)
{
case 1: // 如果x==1
printf("x=1\n");
case 3: // 如果x==3
printf("x=3\n");
break;
default: // 如果x!=2 并且 x!=3
printf("x!=2、x!=3\n");
}
system("pause");
return 0;
}
结果:
我们得到两点结论:
1、如果上面的条件成立了,但是没有写break,那么执行了语句之后还会继续往下执行不会退出分支语句
2、当上面的条件成立了之后如果没有写break,那么继续往下执行的时候就不会再判断case了,只有等到break;才会退出,或者一直执行完。
底层刨析代码:
#include
#include
int main()
{
__asm mov eax,eax;
int x = 1;
switch(x)
{
case 2: // 如果x==1
printf("x=2\n");
break;
case 3: // 如果x==3
printf("x=3\n");
break;
default: // 如果x!=2 并且 x!=3
printf("x!=2、x!=3\n");
}
system("pause");
return 0;
}
__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四条件:
#include
#include
int main()
{
__asm mov eax,eax; // 此处设置断点
int x = 1;
if(x == 1)
printf("x=1\n");
else if(x == 2)
printf("x=2\n");
else if(x == 3)
printf("x=3\n");
else if(x == 4)
printf("x=4\n");
else
printf("x!=1、2、3、4\n");
system("pause");
return 0;
}
ctrl+alt+f7重新生成、F5调试、ALT+8反汇编:
可以看到if else语句条件多与少是没有区别的。
示例代码switch:
#include
#include
int main()
{
__asm mov eax,eax;
int x = 1;
switch(x)
{
case 1:
printf("1\n");
break;
case 2:
printf("2\n");
break;
case 3:
printf("3\n");
break;
case 4:
printf("4\n");
break;
default:
printf("x!=1、2、3、4\n");
}
system("pause");
return 0;
}
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那么灵活。
结语
文章到这里就结束了,感谢大家观看!另外如果有错,还请一定指出;如果有听不懂,一定要问。
封面:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)