代码度量

本章解释了 Coco 支持的代码度量。这些度量仅在仅包含一个仪器化语句的源代码上计算。这可以避免只包含声明的头文件影响整体统计。

eLOC – 有效代码行数

有效行度量测量代码段中的有效行数。一个有效行是包含产生可执行代码的语句的行。

在计算有效代码行时,Coco 忽略

  • 空行
  • 注释行
  • 声明

此度量比简单地计算源代码项目中的行数更精确,因为它跳过了非功能性代码。

McCabe 度量 – 循环复杂性

循环复杂性是托马斯·J·麦卡贝(Thomas J. McCabe, Sr.)提出的代码复杂度度量。它是一个严格正数,表示程序复杂度。具有大于10的循环复杂性的函数通常被认为是难以维护的,因为它包含太多的分支、switch或case语句或循环。

定义

在像 C++ 和 C# 这样的结构化编程语言中,代码的 McCabe 复杂度是

McCabe = 分支 + 函数

在这个等式中,分支表示二元分支语句的数量,函数是代码中函数的数量。

代码中的二元分支语句按照以下方式计数

  • 一个if(...) ... else ...语句算作一个二元分支,同样一个单独的if(...) ...语句:两者都包含两种不同执行路径的选择。
  • 循环结构,如while(...) ...for(...) ...,也计数一个二元分支语句,因为它包含一个提供留在循环中或退出循环的选择的条件。
  • 有一个带有case标注的switch(...) { case ...: ... }结构算作两个二元分支,因为它可以用if(...) ... else ...语句模拟。

属性

McCabe复杂性具有多个特性,这些特性将其与eLOC区分开来

  • McCabe与函数的源代码行数无关:代码中语句的数量并不重要,重要的是分支的数量。
  • 该指标完全独立于编码风格。代码重构不会影响它。这与eLoc和其他衡量代码行数的指标有很大不同。
  • 该指标随函数复杂度的增长而线性增长。例如,在函数中某处添加一个if (...) ... else ...语句会使指标增加一。无论是嵌套在这个选择语句中还是位于函数的开始处,它都不会呈指数增长。
  • 对于单个函数,McCabe指标易于理解,但源文件、类或应用程序的值难以理解。原因是函数调用不在流程图中表示。McCabe指标为每个函数独立计算,就好像源代码中没有交互的函数一样。
  • McCabe指标不适合衡量软件架构的复杂性。或者换句话说,它不能处理将复杂性分布在多个类中的复杂C++/C#设计模式。
  • 像所有指标一样,McCabe指标仅衡量代码复杂性,不衡量数据结构的复杂性。

eLOC与McCabe – 选择哪个指标?

通常,对于衡量函数的复杂性,McCabe方法更有用,因为测量仅依赖于代码结构。代码风格和注释对其没有影响。

但是,一旦分析整个文件或类,即使是困难的,甚至难以解释。原因是McCabe值随代码中函数数量的增加而增加,而不管函数复杂度如何。在这种情况下,有效代码行数当然更容易理解。

Metric of McCabe的变体

Coco生成McCabe指标的替代变体来处理switch/case语句的复杂性。

分组情况下的McCabe

McCabe是一个依赖语句图的指标,但该图通常不是唯一的。特别是在switch/case的情况下,处理连续情况的方式是未定义的。

例如

switch( a )
{
    case 0:
    case 1:
    case 2:
        return true;
    default:
        return false;
}

如果我们将每个case视为一个单独的分支,则该语句的McCabe复杂性为4。但也可能将case 0:case 1:case 2:视为语句图的一个分支。在这种情况下,整个代码的复杂性将仅为2。

Coco支持这种对McCabe的解释,并称此指标为分组情况下的McCabe

压缩开关的McCabe

通常,switch/case语句用于执行非常简单的计算,但这种语句的使用会增加McCabe复杂度,以及开发者的感觉复杂度。

例如

switch( day )
{
    case 0: return "Monday";
    case 1: return "Tuesday";
    case 2: return "Wednesday";
    case 3: return "Thursday";
    case 4: return "Friday";
    case 5: return "Saturday";
    case 6: return "Sunday";
}

虽然McCabe复杂度为7,但这种代码实际上并不比单个if...then...else...语句更复杂。

为了处理此用例,Coco提供了一种名为Mccabe 简化开关的度量标准,该标准认为无论case的数量如何,switch/case的整体复杂度都是1。因此,在此情况下,此样本的复杂度是1。

注意:Mccabe 简化开关不符合Mccabe的定义,因此如果项目需要使用Mccabe度量标准进行分析,则不应使用该度量标准。

Coco v7.2.0©2024 The Qt Company Ltd.
Qt及其相关标志是芬兰以及在全世界其他国家的The Qt Company Ltd.的商标。所有其他商标均为其各自所有者的财产。