开关案例陈述的循环复杂性

时间:2015-05-14 14:43:12

标签: cyclomatic-complexity

我对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,用这个图表 CC diagram

(边缘是17,而不是16,我认为这是一个错字)

它说我们只需要将案例0和案例1统计为一个

但我认为图表应该是: CC diagram

边缘: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语句。

然后我们得到这个图:
enter image description here

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

我是对的..? 真的,真的,真的很困惑......

3 个答案:

答案 0 :(得分:3)

我工作的代码指标工具将每个案例统计为一个单独的分支,即使它是一个堕落案例。

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

减少由switch语句引起的圈复杂度的首要答案是将case / outputs转换为字典。在您的示例中,它将类似于下面的代码示例。请注意,这仅用于可读性/可维护性。如果你的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]);
}

答案 1 :(得分:3)

好的,我找到了答案。

来自McCabe.com

Sending emails with attachment in C#

第26页和第27页

答案是5,因为McCabe的CC原始版本将一个落空案例计为1。

答案 2 :(得分:0)

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

如果你把它算作一个方法体,cc将是8,因为该方法算作直通路径。

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