子程序中的多处返回
return语句放入循环的指导原则:如果能增强代码的可读性就是用return,用防卫子句来简化复杂的错误处理
混乱的代码,遮盖了正常执行路径:
if(file.validName())
{
if(file.open())
{
if(encrypyionKey.valid())
{
losts of code
}
}
}
使用防卫子句,澄清正常路径的代码:
if(file.validName())
{
return -1;
}
if(file.open())
{
return -2;
}
if(encrypyionKey.valid())
{
return -3;
}
losts of code
递归
递归: 当问题的小部分很容易解决,而问题又很容易分解成众多的小部分时,常常会用到递归。对于小范围的问题,使用递归会带来简单、优雅的解,对于大多数问题,它所带来的解将会是极其复杂的,使用简单的迭代通常会比较容易理解。
递归的例子:
BOOLEAN function FindPathThroughMaze ( MAZE_T MAZE , POINT Position )
{
/*负责检查这个点有没有尝试过*/
if (alreadyTried(Maze,Position))
return(FALSE);
/* 负责检查该点是不是迷宫的出口,退出递归的标志 */
if (ThisIsTheExit(maze,Position))
return(TRUE);
/* 记录这一点已经尝试过了,防止出现无穷递归 */
RememberPosition(Maze,Position);
if ( MoveLeft( Maze , Position , &NewPosition ) )
if ( FindPathThroughMaze ( Maze , NewPosition ) )
return( TRUE );
if ( MoveUp( Maze , Position , &NewPosition ) )
if ( FindPathThroughMaze ( Maze , NewPosition ) )
return (TRUE);
if ( MoveDown ( Maze , Position , &NewPosition ) )
if ( FindPathThroughMaze ( Maze , NewPosition ) )
return (TRUE );
if ( MoveRight ( Maze , Position , &NewPosition ) )
if ( FindPathThroughMaze ( Maze , NewPosition ) )
return ( TRUE);
return( FALSE );
}
使用递归的技巧:
1、确认递归能够停止:有判断递归退出的语句
2、使用安全计数器防止出现无穷递归:在子程序中如果超出了递归调用次数安全上限,就强制退出
3、留心栈空间:防止出现栈越界
4、不要用递归去计算阶乘或者斐波纳契数列:使用for循环简单的,就不要去使用递归
goto语句
1、使用多种编程方式替代goto:
(1)嵌套使用if语句
(2)用一个状态标志位重写代码:每执行一小段代码都需要去判断标志位,如果标志位和初始化时不一样了,那么后面的代码就不执行了,一直到错误处理的时候再执行。
(3)在编写代码时一定不要相同代码重复写多次,可以修改if检测条件,想办法让他们执行在一起。
2、使用goto的注意事项
(1)如果没有return的话,goto 也会顺序执行下去
(2)goto应该尽可能的不去使用,使用其他方式代替;即便是必须去使用,在一个子程序中最好只使用一次。
编程核对表
goto
· goto 是最后的选择吗?用 goto 使程序更好读更好维护吗?
· 用 goto 是为效率的目的吗?用 goto 达到此目的了吗?
· 一个程序是否只用一个 goto 呢?
· goto 只转向前面的程序段而不是转向其后面的程序段吗?(后面指已执行过程序)
· goto 所转向的标号都有了吗?
return
· 每个子程序的 return 数目是否最少?
· return 增强了可读性了吗?
递归调用
· 用递归调用的代码含使递归结束的语句吗?
· 程序设置了安全计数器来保证递归调用终止了吗?
· 是否只在一个程序中用递归调用?
· 递归调用的深度是否限制在程序堆栈容量可满足的条件下?
· 递归调用是实现程序的最优途径吗?它比循环更简单吗?
小节
1、多个return可以增强子程序的可读性和可维护性,同时可以避免产生很深的嵌套逻辑。但是使用它的时候要多加小心。
2、递归可以优雅的解决一小部分问题,对它的使用也要加倍小心。
3、在少数情况下,goto是编写可读性和可维护性代码的最佳方法,但这种情况非常罕见。除非万不得已,否则不要使用goto。