《编写高质量代码:改善c程序代码的125个建议》——建议17-4:对深层嵌套的if语句进行重构

简介:

本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第3章,建议17-4,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议17-4:对深层嵌套的if语句进行重构

在代码中,如果某个函数的if语句嵌套太深,为了程序的可读性、可维护性与效率,我们应该尽量想办法进行重构,以减少if语句的嵌套层数,如下面的示例代码所示:

int main (void)
{
    int x=0;
    int a=1;
    int b=3;
    int c=5;
    int d=7;
    if(a<b)
    {
            x+=b;
            if(b<c)
            {
                    x+=c;
                    if(c<d)
                    {
                            x++;
                            if(a>d)
                            {
                                    x=d;
                            }
                    }
            }
    }
    printf("%d",x);
    return 0;
}

在上面这个简单的示例代码中,我们使用了4层if嵌套。为了减少程序中if语句的嵌套层数,我们首先能够想到的办法就是可以通过重复检测条件中的某一部分来简化嵌套的if语句,如下面的示例代码所示:

int main (void)
{
    int x=0;
    int a=1;
    int b=3;
    int c=5;
    int d=7;
    if(a<b)
    {
            x+=b;
            if(b<c)
            {
                    x+=c;
            }
    }
    if(a<b&&b<c&&c<d)
    {
            x++;
            if(a>d)
            {
                    x=d;
            }
    }
    printf("%d",x);
    return 0;
}

通过上面的代码,我们可以清楚地看到通过重复检测条件中的某一部分来简化嵌套的if语句的办法并不能无偿地减少嵌套层数。同时,作为减少嵌套层数的代价,必须容忍使用一个更复杂的判断。也就是说,虽然这样减少了if语句的嵌套层数,但增加了一些复杂的判断,让我们有点得不偿失的感觉。
既然我们对通过重复检测条件中的某一部分来简化嵌套的if语句的办法不是很满意,那么我们还可以使用 if/break块来简化if语句的嵌套层数。上面的示例代码采用if/break块重构后如下所示:

int main (void)
{
    int x=0;
    int a=1;
    int b=3;
    int c=5;
    int d=7;
    do{    
            if(a>=b) 
                    break;    
            x+=b;  
            if(b>=c) 
                    break;    
            x+=c;  
            if(c>=d) 
                    break;    
            x++;  
            if(a<=d) 
                    break;    
            x=d;  
    } while(false);
    printf("%d",x);
    return 0;
}

从上面的代码可以看出,相对于通过重复检测条件中的某一部分来简化嵌套的if语句的办法,if/break块真正地实现了逻辑的扁平化,减少了if语句的嵌套层数,从而使代码看起来比较清晰,增加了程序的可读性。与此同时,该方法还不会增加复杂的条件判断,从而可以避免因为重构而导致的if条件出错。当然,你还可以使用它的另外两个相似的if/return和if/goto块来达到同样的效果,但这种方法唯一的缺陷就是破坏了程序的内聚性。
除了上面的两种方法之外,我们还可以通过把代码分割开来,把深层嵌套的if语句抽取出来放进单独的函数中。这样,不仅减少了if语句的嵌套层数,同时,一个好的函数名对代码也具有自我注解的作用,在一定程度上也可以提高程序的可读性。但这种方法与前面的方法一样,程序逻辑的复杂度依然存在,甚至更复杂。
因此,如有可能,我们应该选择完全重新设计深层嵌套的代码。在通常情况下,如果程序中存在着比较复杂的逻辑代码,就说明你还没有充分地理解程序,从而无法简化它。所以对程序员来说,深层嵌套的if语句也是一个警告,它说明你要么想办法进行重构,要么重新设计该程序。

相关文章