设为首页 加入收藏

TOP

5.2 if…else…语句(1)
2013-10-07 14:30:21 来源: 作者: 【 】 浏览:56
Tags:5.2 else 语句

5.2 if…else…语句(1)

5.1节讲述了if语句的构成,但是,只有if的语句是不完整的分支结构,图5-1对比了两种语句结构的执行流程。

 
图5-1 if与if…else…结构对比

如图5-1所示,if语句是一个单分支结构,if…else…组合后是一个双分支结构。两者间完成的功能有所不同。从语法上看,if…else…只比if语句多出了一个else。else有两个功能,如果if判断成功,则跳过else分支语句块;如果if判断失败,则进入else分支语句块中。有了else语句的存在,程序在进行流程选择时,必会经过两个分支中的一个。通过代码清单5-3,我们来分析else如何实现这两个功能。

代码清单5-3 if…else…组合—Debug版

  1. // C++(www.cppentry.com)源码说明:if…else…组合   
  2. if (argc == 0) {  
  3.     // 执行if语句块   
  4.     printf("argc == 0");  
  5. }else{  
  6.     // 执行else语句块  
  7.     printf("argc != 0");  
  8. }  
  9.  
  10. // C++(www.cppentry.com)源码与对应汇编代码讲解  
  11. // C++(www.cppentry.com)源码对比,比较参数变量argc == 0  
  12. if (argc == 0)  
  13. ; 使用变量argc减去0  
  14. 004010B8   cmp         dword ptr [ebp+8],0  
  15. ; 使用条件跳转JNE,检查cmp影响标记位  
  16. ; 跳转成立,跳转到地址0x004010CD处,即else语句块的首地址  
  17. 004010BC   jne         IfElse+2Dh (004010cd)  
  18. {  
  19. // C++(www.cppentry.com)源码对比,进入if语句块,调用printf函数   
  20. printf("argc == 0");  
  21. ; printf函数汇编讲解略  
  22. }else  
  23. ; 直接跳转到地址0x004010DA地址处,当if语句执行后跳转过else语句块  
  24. 004010CB   jmp         IfElse+3Ah (004010da)  
  25. {  
  26. // C++(www.cppentry.com)源码对比,进入else语句块,调用printf函数  
  27. printf("argc != 0");  
  28. ; printf函数汇编讲解略  
  29. 004010CD   push        offset string "argc != 0" (00420030)  
  30. 004010D2   call        printf (00401150)  
  31. 004010D7   add         esp,4  
  32. }  
  33. ; else语句结束处  
  34. 004010DA   pop         edi 

在代码清单5-3中,if语句转换的条件跳转和代码清单5-1中的if语句相同,都是取相反的条件跳转指令。而在else处(地址004010CB)多了一句jmp指令,这是为了在if语句比较后,如果结果为真,则程序流程执行if语句块并且跳过else语句块,反之执行else语句块。else处的jmp指令跳转的目标地址为else语句块结尾处的地址,这样的设计可以跳过else语句块,实现两个分支语句二选一的功能。

4.2.3节介绍了条件表达式,当条件表达式中的表达式2或表达式3为变量时,没有进行优化处理。条件表达式转换后的汇编代码和if…else…结构非常相似,将代码清单4-17与代码清单5-3进行分析对比可以发现,两者间有很多相似之处,如没有源码比照,想要分辨出是条件表达式还是if…else…结构实在太难。它们都是先比较,然后再执行条件跳转指令,最后进行流程选择的。

通常,VC++(www.cppentry.com) 6.0对条件表达式和if…else…使用同一套处理方式。代码清单5-3对应条件表达式转换方式4。将代码清单5-3稍作改动,改为符合条件表达式转换方式1的形式,如代码清单5-4所示。

代码清单5-4 模拟条件表达式转换方式1

  1. // C++(www.cppentry.com)源码说明:if…else…模拟条件表达式转换方式1  
  2. if (argc == 0){         // 等价条件表达式中的表达式1  
  3.     // 修改上例,将上例中的printf函数替换成变量赋值语句  
  4.     argc = 5;           // 等价条件表达式中的表达式2  
  5. }else{  
  6. // 代码上例,将上例中的printf函数替换成变量赋值语句  
  7.     argc = 6;           // 等价条件表达式中的表达式3  
  8. }  
  9. // 防止变量被优化处理  
  10. printf("%d \r\n", argc);  
  11.  
  12. // Debug调试版,由于注重调试功能,没有进行优化,反汇编讲解如下  
  13. 22:     if (argc == 0){  
  14. ; 直接与0进行比较,注意后面的jne,如果不相等就跳走,C源码中的逻辑与汇编代码相反  
  15. 00401098   cmp         dword ptr [ebp+8],0  
  16. 0040109C   jne         main+27h (004010a7)  
  17. 23:       argc = 5;  
  18. ; 这里是if语句块的内容,将参数赋值为5  
  19. 0040109E   mov         dword ptr [ebp+8],5  
  20. 24:     }else{  
  21. ; 注意这里的跳转,正好跳出了else块  
  22. 004010A5   jmp         main+2Eh (004010ae)  
  23. 25:       argc = 6;   
  24. ; 这里是else语句块的内容,将参数赋值为6  
  25. 004010A7   mov         dword ptr [ebp+8],6  
  26. 26:     }  
  27. 27:     printf("%d \r\n", argc);  
  28. ; printf函数汇编讲解略  
  29. 004010AE ...... 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇5.2 if…else…语句(2) 下一篇5.4 switch的真相(4)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: