Цикломатическая сложность оператора switch case

Я запутался в CC оператора switch

Если у меня есть следующий код:

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");
}

что такое ЦК?

Я нашел сообщение, в котором говорилось, что это 5, с этой диаграммой Диаграмма CC

(краев 17, а не 16, думаю опечатка)

В нем говорится, что нам нужно только считать случай 0 и случай 1 как один

Но я думаю, что диаграмма должна быть: CC диаграмма

Ребра: 17,
Узлы: 13,
17 - 13 + 2П = 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

я прав..?
действительно, действительно, очень запутался...


person CodinCat    schedule 14.05.2015    source источник


Ответы (3)


Хорошо, я нашел ответ.

с сайта McCabe.com

http://www.mccabe.com/pdf/mccabe-nist235r.pdf

стр. 26 и 27

Ответ — 5, потому что в оригинальной версии CC Маккейба случай провала считается за 1.

person CodinCat    schedule 15.05.2015

Инструменты метрики кода, с которыми я работал, считают каждый случай отдельной ветвью, даже если это случай провала.

Но это произвольный выбор. Инструменты метрик кода по умолчанию склонны ошибаться в сторону осторожности. То, как в конечном итоге будет оцениваться оператор switch, является внутренней деталью реализации, которая зависит от типа ввода и количества случаев (по крайней мере, в C#).

Ответ для уменьшения цикломатической сложности, вызванной операторами switch, заключается в преобразовании случаев/выходных данных в словарь. В вашем примере это будет что-то вроде примера кода ниже. Имейте в виду, что это только для удобства чтения/сопровождения. Если ваш оператор 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]);
}
person Seth    schedule 14.05.2015
comment
спасибо за Ваш ответ. Я узнаю о цикломатической сложности и просто хочу знать, как ее рассчитать. - person CodinCat; 14.05.2015

Правильный ответ — 7. Каждый случай в операторе switch считается за 1, поэтому 5 x 1 = 5. Если считается за 1, то else засчитывается за 1. Таким образом, 1 + (5 x 1) + 1 = 7.

Если бы вы считали это телом метода, cc было бы равно 8, поскольку метод считается прямым путем.

Пожалуйста, измените принятый ответ на правильный, так как 5 - неправильный ответ.

person Marton Berecz    schedule 28.04.2018