цикломатическая сложность = 1 + #операторы if?

Я нашел следующий абзац, касающийся цикломатической сложности Википедии:

можно показать, что цикломатическая сложность любой структурированной программы с одной точкой входа и одной точкой выхода равна числу точек решения (т. е. операторов "if" или условных циклов), содержащихся в этой программе плюс один.

это означало бы цикломатическую сложность 3 для двух произвольных вложенных, если заявления:

if (a)
{
    if (b)
    {
        foo();
    }
    else
    {
        bar();
    }
}
else
{
    baz();
}

поскольку будет вызвана ровно одна из трех функций, моя кишка согласна с 3.

однако два произвольных оператора if также могут быть записаны последовательно вместо их вложенности:

if (a)
{
    foo();
}
else
{
    bar();
}

if (b)
{
    baz();
}
else
{
    qux();
}

сейчас есть четыре пути через код:

  • фу, баз
  • foo, qux
  • бар, баз
  • bar, qux

не должна ли цикломатическая сложность этого фрагмент отсюда будет 4 вместо 3?

Я неправильно понял цитируемый абзац?

2 ответов


цикломатическая сложность определяется как количество линейно независимых путей через код.

во втором примере у нас есть следующие пути, которые выполняются...

| # |   A   |    B  |  Nodes hit   |
| 1 | true  | true  |  foo() baz() |
| 2 | true  | false |  foo() qux() |
| 3 | false | true  |  bar() baz() |
| 4 | false | false |  bar() qux() |

вы совершенно правы, что количество путей выполнения здесь-4. И все же цикломатическая сложность равна 3.

ключ в понимании того, что цикломатическая сложность измеряет:

определение:

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

от http://www.ironiacorp.com/

4-й путь не линейно независим от первых трех путей, поскольку он не вводит никаких новых узлов / программных операторов, которые не были включены в первые три пути.

Как уже упоминалось на Википедия, цикломатическая сложность всегда меньше или равна числу теоретических уникальных путей потока управления и всегда больше или равна минимальному числу реально достижимых путей выполнения.

(чтобы проверить второе утверждение, представьте, что b == a было всегда true при вводе блока кода, который вы описали).


Я согласен с объяснением перфекционист. Вот более неформальное объяснение в случае языка Java:

цикломатическая сложность Маккейба (McCC) для метода выражается как количество независимых путей потока управления в нем. Он представляет собой нижнюю границу для количества возможных путей выполнения в исходном коде и в то же время верхнюю границу для минимального количества тестовых случаев, необходимых для достижения полного охвата теста ветви. Значение метрика рассчитывается как число следующих инструкций плюс 1: if, for, foreach, while, do-while, case label (который принадлежит инструкции switch), catch, conditional statement (?:). Кроме того, логические выражения "и" (&&) и "или" (||) также добавляют 1 к значению, поскольку их оценка короткого замыкания может вызвать ветвление в зависимости от первого операнда. Следующие инструкции не включены: else, switch, метка по умолчанию (которая принадлежит инструкции switch), попробуйте, в конечном счете.