用汇编的眼光看C++(之退出流程)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
无论是在判断还是在循环的过程中,通常在遇到合适的条件的时候就会退出相应的模块。跳出模块运行的方式很多,break,continue,return都可以。下面我们就可以分别对他们进行将介绍。
(1)continue只能用于循环,而break循环、判断都可以应用。两者有什么区别呢?
- 21: for(int m = 10; m < 100; m ++)
- 00401638 mov dword ptr [ebp-4],0Ah
- 0040163F jmp process+2Ah (0040164a)
- 00401641 mov eax,dword ptr [ebp-4]
- 00401644 add eax,1
- 00401647 mov dword ptr [ebp-4],eax
- 0040164A cmp dword ptr [ebp-4],64h
- 0040164E jge process+55h (00401675)
- 22: {
- 23: if(m / 20 == 3)
- 00401650 mov eax,dword ptr [ebp-4]
- 00401653 cdq
- 00401654 mov ecx,14h
- 00401659 idiv eax,ecx
- 0040165B cmp eax,3
- 0040165E jne process+42h (00401662)
- 24: {
- 25: break;
- 00401660 jmp process+55h (00401675)
- 26: }
- 27:
- 28: if(m / 10 == 0)
- 00401662 mov eax,dword ptr [ebp-4]
- 00401665 cdq
- 00401666 mov ecx,0Ah
- 0040166B idiv eax,ecx
- 0040166D test eax,eax
- 0040166F jne process+53h (00401673)
- 29: {
- 30: continue;
- 00401671 jmp process+21h (00401641)
- 31: }
- 32: }
- 00401673 jmp process+21h (00401641)
(2)goto一般用的情况不多,但是有一种情况例外?
- void process()
- {
- if(/* get resources one */ == 0)
- {
- return;
- }
- if(/* get resource two */ == 0)
- {
- /* free resource one */
- return;
- }
- if(/* get resource three */ == 0)
- {
- /* free resource two */
- /* free resource one */
- return;
- }
- if(/* get resource four */ == 0)
- {
- /* free resource three */
- /* free resource two */
- /* free resource one */
- return;
- }
- /* ... */
- }
- void process()
- {
- if(/* get resources one */ == 0)
- {
- return;
- }
- if(/* get resource two */ == 0)
- {
- goto fail_one;
- }
- if(/* get resource three */ == 0)
- {
- goto fail_two;
- }
- if(/* get resource four */ == 0)
- {
- goto fail_three;
- }
- /* ... */
- fail_three:
- /* free resource three */
- fail_two:
- /* free resource two */
- fail_one:
- /* free resource one */
- return;
- }
(3) return也是跳出代码段一个很好的方法。
它不光可以在函数中使用,也可以灵活运用在循环语句、判断语句中。要是在递归语句中,更是少不了他的身影。比如说,我们现在查看一个字符串是否满足这样一个结构:
str = ab | a str b;
那么换成函数代码应该怎么编写呢?大家可以自己先试一试,下面是我的一个方法:
- BOOL process_multi_char(const char* str, int length)
- {
- if(2 == length)
- return !strncmp(str, "ab", strlen("ab")) ? TRUE : FALSE;
- if(str[0] == 'a' && str[length -1] == 'b')
- return process_multi_char(str+1, length-2);
- else
- return FALSE;
- }
- BOOL process(const char str[], int length)
- {
- if(NULL == str || length < 2 || (0 != length % 2))
- return FALSE;
- return process_multi_char(&str[0], length);
- }
这里return的好处就是充分把字符串进行了拆分。我们按照定义,先从基本的问题下手,大事化小,小事化了。当然这里的小事就是字符串这有两个字符的情形,也是最底层函数的出口。要不然函数就会一致不停地处理下去,这是没有意义的。计算过程中一旦发现了不合法的运算,那么整个迭代的过程就会结束,快速回溯,输出结果。所以说要想写好递归或者是用到堆栈结构的代码时,必须考虑代码的入口和出口的把握,而return就是最好的选择,什么时候return,什么时候迭代都要把握时机,否则很容易陷入到死循环当中去。