首页 > 其他分享 >函数圈复杂度

函数圈复杂度

时间:2024-10-15 23:14:06浏览次数:6  
标签:语句 函数 int 代码 else 复杂度

函数圈复杂度(Cyclomatic Complexity),也称为圈复杂度麦凯布复杂度,是衡量代码复杂度的一种指标。它由计算一个函数或模块中独立执行路径的数量得出,反映了程序的控制流复杂性。

圈复杂度的核心思想是,函数的复杂性越高,代码中的分支、循环和条件判断越多,程序的独立路径数就越多。因此,圈复杂度越高,代码可能越难以理解、测试和维护。

计算方法

函数圈复杂度的基本计算公式是:

M = E - N + 2P
  • M:圈复杂度(Cyclomatic Complexity)。
  • E:控制流图中的边数(Edges),即程序中的控制转移路径(例如从一个语句到另一个语句)。
  • N:控制流图中的节点数(Nodes),即程序中的代码块(例如一个条件判断、循环、或者简单的赋值语句)。
  • P:程序中的连通分量数(Connected components),对于大多数函数来说,P = 1。

在大多数情况下,可以使用一个更简单的方法来估算圈复杂度:计算函数中的控制结构。每遇到一个控制结构,如ifelse ifforwhileswitch case等,圈复杂度就增加1。

圈复杂度的简单规则

  • 没有分支的直线代码:圈复杂度为1。
  • 每个if语句或else if分支:圈复杂度增加1。
  • 每个forwhile循环:圈复杂度增加1。
  • 每个switch语句的case子句:每个case增加1。
  • 每个catch语句:增加1。

示例代码和圈复杂度计算

示例 1:简单函数

int add(int a, int b) {
    return a + b;
}

这个函数没有任何条件分支或循环,圈复杂度为 1

示例 2:带有if-else语句的函数

int max(int a, int b) {
    if (a > b) {
        return a;
    } else {
        return b;
    }
}
  • 这里有一个if-else结构,圈复杂度为 2,因为有两个独立路径。

示例 3:带有if-else和循环的函数

int findMax(const std::vector<int>& nums) {
    int max = nums[0];
    for (int i = 1; i < nums.size(); ++i) {
        if (nums[i] > max) {
            max = nums[i];
        }
    }
    return max;
}
  • 这里有一个for循环和一个if条件判断:
    • for循环:圈复杂度增加1。
    • if语句:圈复杂度增加1。
    • 初始复杂度为1(没有控制结构的情况下)。
  • 圈复杂度总计为 3

圈复杂度的重要性

圈复杂度越高,函数的复杂性越高,可能带来以下问题:

  1. 可读性下降:复杂的控制流结构使得代码更难理解和维护。
  2. 测试难度增加:需要更多的测试用例来覆盖所有的独立执行路径,确保代码的正确性。
  3. 错误风险增加:复杂的代码往往更容易引入错误,尤其是在修改和扩展时。

圈复杂度的最佳实践

  • 圈复杂度不应过高,一般来说一个函数的圈复杂度应尽量保持在10以下。对于复杂度超过10的函数,应该考虑重构代码,划分为多个更简单的函数。
  • 单一职责原则:一个函数只应该做一件事,遵循这一原则可以有效降低圈复杂度。
  • 早期返回(early return):通过减少嵌套层级来降低复杂度。
  • 重构:如果发现函数复杂度过高,可以尝试将代码中的不同逻辑分解为多个小函数。

总结

函数圈复杂度是衡量代码复杂性的重要指标,它与代码中的分支和循环直接相关。圈复杂度越高,代码越难测试、理解和维护。合理控制代码的圈复杂度是写出可维护、高质量代码的关键之一。

标签:语句,函数,int,代码,else,复杂度
From: https://www.cnblogs.com/chentiao/p/18468739

相关文章

  • c++如何使用pthread_join函数配合pthread_create函数来创建和等待线程完成,实现线程同
    在C++中,pthread_create 和 pthread_join 是POSIX线程库(pthread)的一部分,用于创建和管理线程。pthread_create 用于创建一个新的线程,而 pthread_join 用于等待一个线程的执行完成,从而实现线程同步与控制。基本步骤使用 pthread_create 函数创建一个线程。线程的工作由......
  • C++中的回调函数
    回调函数(callbackfunction)是指作为参数传递给另一个函数的函数,在某个事件发生或某个任务完成时被调用。回调函数在异步编程中非常常见,因为它们允许代码在某个操作完成后自动执行某些行为,而无需阻塞程序。回调函数的基本特征作为参数传递:回调函数通常是作为参数传递给另一个函......
  • 第九章习题3-编写一个函数print,打印一个学生的成绩数组,该数组有5个学生的数据记录,每个
     ......
  • C++中的不安全函数
    不安全函数(UnsafeFunctions)通常指那些在特定条件下可能导致程序错误、数据损坏或安全漏洞的函数。在编程中,不安全函数可能表现为以下几种情况:缓冲区溢出:当函数在处理数据时没有检查输入的大小,可能导致超出预分配内存空间的写入,造成数据破坏或程序崩溃。例如,在C和C++中,strcpy、......
  • 函数
    Rust代码中的函数和变量名使用snakecase规范风格。在snakecase中,所有字母都是小写并使用下划线分隔单词。这是一个包含函数定义示例的程序:fnmain(){println!("Hello,world!");another_function();}fnanother_function(){println!("Anotherfuncti......
  • Python学习流水账Day5——有关Python中的函数
    文章目录前言一、Python中的函数1.内置函数2.定义一个函数调用函数为函数设置参数实参形参给函数设置多个形参默认形参函数的返回值函数的变量局部变量全局变量3.匿名函数4.递归函数总结前言简单的python复习第五天:不是用来教学的,上班没劲,主打一个本科毕业没竞......
  • C++的仿函数functor
    C++的仿函数functor详细内容仿函数(Functor)是C++中的一种设计模式,也叫函数对象。仿函数是一个重载了operator()的类或结构体,它可以像普通函数一样被调用。这使得它具有类似函数的行为,但实际上它是一个对象,因此可以拥有状态(成员变量)和更多的灵活性。仿函数的主要用途是:可以......
  • OpenCV高级图形用户界面(11)检查是否有键盘事件发生而不阻塞当前线程函数pollKey()的
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述轮询已按下的键。函数pollKey无等待地轮询键盘事件。它返回已按下的键的代码或如果没有键自上次调用以来被按下则返回-1。若要等待按键被按下,请使用waitKey。注意waitKey......
  • OpenCV高级图形用户界面(8)在指定的窗口中显示一幅图像函数imshow()的使用
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述在指定的窗口中显示一幅图像。函数imshow在指定的窗口中显示一幅图像。如果窗口是以cv::WINDOW_AUTOSIZE标志创建的,图像将以原始大小显示,不过仍然受限于屏幕分辨率。否则,图像......
  • OpenCV高级图形用户界面(9)更改指定窗口的位置函数moveWindow()的使用
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述将窗口移动到指定的位置。cv::moveWindow()函数用于更改指定窗口的位置。你可以使用这个函数来移动窗口到屏幕上的任何位置。函数原型voidcv::moveWindow ( constString......