圈复杂度QAQ

参考链接:链接1

基本概念

圈复杂度(Cyclomatic complexity,简写CC)也称为条件复杂度,是一种代码复杂度的衡量标准。由托马斯·J·麦凯布(Thomas J. McCabe, Sr.)于1976年提出,用来表示程序的复杂度,其符号为VG或是M。它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,也可理解为覆盖所有的可能情况最少使用的测试用例数。圈复杂度大说明程序代码的判断逻辑复杂,可能质量低且难于测试和 维护。程序的可能错误和高的圈复杂度有着很大关系。

计算方法

1. 点边计算法

对于一个控制流图的圈复杂度,其计算公式为: V ( G ) = E − N + 2 V(G) = E - N + 2 V(G)=EN+2

其中, E E E为控制流图中边的数量, N N N为节点数量。

举几个栗子:

顺序结构的圈复杂度为(无论多长的顺序结构):1

while循环圈复杂度(增加一个while循环圈复杂度+1):2

if-else圈复杂度(增加一个if分支圈复杂度+1):2

Until同while

https://i-blog.csdnimg.cn/blog_migrate/525fafa30a702aedd0c85ce789c12cef.png

2. 节点判别法

通过上述的点边计算法,可以发现,增加while分支或是if分支,圈复杂度就会+1,所以不难发现,每增加一个判定节点,圈复杂度就会+1,计算公式如下:

V ( G ) = P + 1 V(G) = P + 1 V(G)=P+1

其中 P P P为判定节点数,主要有如下类型:

  • if语句
  • while语句
  • for语句
  • case语句
  • catch语句
  • and和or布尔操作(判定语句中)
  • ?: 三元操作符

值得注意的是,对于多分支的case结构和if-elseif-else等结构,需要判断时间判定节点数,画个图就清楚了😊

计算栗子

栗子1

void sort(int * A)
{
int i=0;
int n=4;
int j = 0;
while(i < n-1)
{
    j = i +1
    while(j < n)
    {
        if (A[i] < A[j])
             swap(A[i], A[j]);
    }
    i = i + 1
}
}

所以圈复杂度为: V ( G ) = 1 + 1 ( w h i l e ) + 1 ( w h i l e ) + 1 ( i f ) = 4 V(G) = 1 + 1(while) + 1(while) + 1(if) = 4 V(G)=1+1(while)+1(while)+1(if)=4

当然也可以使用点边计算法计算

栗子2

U32 find (string match){
         for(auto var : list)
         {
             if(var == match && from != INVALID_U32) return INVALID_U32;
         }
         //match step1
         if(session == getName() && key == getKey())
         {
             for (auto& kv : Map)
             {
                 if (kv.second == last && match == kv.first)
                 {
                     return last;
                 }
             }

         }
         //match step2
         auto var = Map.find(match);
         if(var != Map.end()&& (from != var->second)) return var->second;

         //match step3
         for(auto var: Map)
         {
             if((var.first, match) && from != var.second)
             {
                 return var.second;
             }
         }
         return INVALID_U32;
};

圈复杂度: V ( G ) = 1 + 1 ( f o r ) + 2 ( i f , a n d ) + 2 ( i f , a n d ) + 1 ( f o r ) + 2 ( i f , a n d ) + 2 ( i f , a n d ) + 1 ( f o r ) + 2 ( i f , a n d ) = 14 V(G) = 1 + 1(for) + 2(if, and) + 2(if, and) + 1(for) + 2(if, and) + 2(if, and) + 1(for) + 2(if, and) = 14 V(G)=1+1(for)+2(if,and)+2(if,and)+1(for)+2(if,and)+2(if,and)+1(for)+2(if,and)=14

意义

一般来说圈复杂度大于10的方法存在很大的出错风险。圈复杂度和缺陷个数有高度的正相关:圈复杂度最高的模块和方法,其缺陷个数也可能最多。

圈复杂度代码状况可测性维护成本
1-10清晰、结构化
10-20复杂
20-30非常复杂
>30不可读不可测非常高

所以在平时的代码编写过程中要注意降低代码的圈复杂度,可以采用拆分函数和优化表达等方式降低圈复杂度😘

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值