switch case 语句的循环复杂度

Cyclomatic Complexity of switch case statement

我对 switch 语句的 CC 感到困惑

如果我有以下代码:

if (n >= 0) {
    switch(n) {
        case 0:
        case 1: 
            printf("zero or one\n");
            break;
        case 2: 
            printf("two\n");
            break;
        case 3:
        case 4: 
            printf("three or four\n");
            break;
        }
    }
else {
    printf ("negative\n");
}

CC 是什么?

我发现a post说是5,有这个图

(边是17,不是16,我觉得打错了)

说我们只需要将case 0和case 1算作一个

但我认为图表应该是:

边数:17,
节点:13,
17 - 13 + 2P = 6

我把每个案例都算作 1

我的 OOSE 教授说是 6,但方式不同

他说:

init     => 1  
if       => 1  
switch   => 1  
case 0 1 => 1  
case 2   => 1  
case 3 4 => 1

所以应该是 6

正确答案是什么?
我真的很困惑,谢谢。


已编辑:
现在我认为是7。是的,7
因为如果 n 大于 5,将什么都不做并退出 switch 语句。

然后我们得到这张图:

现在 E = 18
18 - 13 + 2 = 7

我说得对吗?
真的,真的,真的很迷茫...

我使用过的代码度量工具将每个案例计为一个单独的分支,即使它是失败的案例。

但这是一个随意的选择。默认情况下,代码度量工具倾向于谨慎行事。最终评估 switch 语句的方式是一个内部实现细节,它会根据输入类型和案例数量(至少在 C# 中)而有所不同。

减少由 switch 语句引起的圈复杂度的首选方法是将 cases/outputs 转换为字典。在您的示例中,它类似于下面的代码示例。请注意,这仅适用于 readability/maintainability。如果您的 switch 语句足够长,.Net 编译器会自动为您将其转换为字典,因此不会提高性能。

var outputs = new Dictionary<int, string>()
            {
                { 0, "zero or one\n" },
                { 1, "zero or one\n" },
                { 2, "two\n" },
                { 3, "three or four\n" },
                { 4, "three or four\n" }
            };

if (n >= 0)
{
    printf(outputs[n]);
}

好的,我找到答案了。

来自 McCabe.com,第 26 和 27 页

答案是 5,因为 McCabe 的 CC 原始版本将失败案例计为 1。

正确答案是 7。 switch 语句中的每个 case 都计为 1,因此 5 x 1 = 5。 if 算作 1。 else 算作 1。 所以, 1 + (5 x 1) + 1 = 7.

如果您将其视为方法的主体,则 cc 将为 8,因为该方法被视为直通路径。

请将您接受的答案更改为正确答案,因为 5 是错误答案。