《编写高质量代码:改善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语句也是一个警告,它说明你要么想办法进行重构,要么重新设计该程序。

相关文章
|
算法 Unix API
指数退避(Exponential backoff)在网络请求中的应用
## 一、背景 最近做云服务 API 测试项目的过程中,发现某些时候会大批量调用 API,从而导致限流的报错。在遇到这种报错时,传统的重试策略是每隔一段时间重试一次。但由于是固定的时间重试一次,重试时又会有大量的请求在同一时刻涌入,会不断地造成限流。 这让我回想起两年前在查阅[Celery Task 文档](http://docs.celeryproject.org/en/latest
13748 1
|
Ubuntu Shell Linux
pyenv 管理多个 Python 版本(1)
pyenv 管理多个 Python 版本(1)
483 86
pyenv 管理多个 Python 版本(1)
|
8月前
|
Kubernetes Cloud Native Serverless
OpenKruise v1.8版本解读:解锁云原生应用管理的无限可能
OpenKruise在2025年2月发布了最新的1.8版本。此版本带来了诸多重要的更新与增强,致力于进一步提升云原生应用管理的效率、弹性和可靠性。
|
9月前
|
存储 JavaScript 算法
Vue 中的虚拟 DOM 是什么,以及它是如何工作的。
Vue 中的虚拟 DOM 是什么,以及它是如何工作的。
285 1
|
10月前
|
人工智能 小程序 API
销售易NeoCRM与纷享销客:功能、体验与价格全解析
销售易NeoCRM和纷享销客是国内知名的CRM解决方案,各有特色。销售易功能全面,涵盖销售、客户、营销管理及AI赋能,适合中大型企业;纷享销客则以强大的连接能力和业务协同见长,用户体验佳,性价比高,更适合中小企业。两者在价格、用户体验和适用场景上有所差异,企业应根据自身需求选择合适的CRM系统。
|
11月前
|
机器学习/深度学习 搜索推荐 数据挖掘
Pandas数据应用:广告效果评估
在数字化营销中,广告效果评估至关重要。Pandas作为Python的强大数据分析库,在处理广告数据时表现出色。本文介绍如何使用Pandas进行广告效果评估,涵盖数据读取、预览、缺失值处理、数据类型转换及常见报错解决方法,并通过代码案例详细解释。掌握这些技能,可为深入分析广告效果打下坚实基础。
242 17
|
开发者 Python
阿里云PAI DSW快速部署服务
在使用阿里云DSW实例进行开发的时候,可能需要快速部署服务测试应用效果。DSW实例目前已经支持通过自定义服务访问配置功能,对外提供服务访问能力,您在应用开发过程中无需分享整个DSW实例,即可将服务分享给协作开发者进行测试和验证。
465 23
|
移动开发 编解码 UED
除了 `<audio>` 和 `<video>` 标签,HTML5 还支持哪些多媒体格式?
【10月更文挑战第19天】HTML5对多种多媒体格式的支持,为网页开发者提供了丰富的选择,能够更好地满足不同类型多媒体内容在网页中的展示和交互需求,提升了网页的用户体验和多媒体应用的多样性。
|
IDE Linux 开发工具
lighttpd1.4.20源码分析:安装与配置
lighttpd1.4.20源码分析:安装与配置
1038 0