web-dev-qa-db-ja.com

switchcaseステートメントの循環的複雑度

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とは何ですか?

私が見つけた 投稿 この図で5だと言った CC diagram

(エッジは16ではなく17です。タイプミスだと思います)

ケース0とケース1を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

私は正しいですか..?
本当に、本当に、本当に混乱しています...

12
CodinCat

わかりました、私は答えを見つけました。

mcCabe.comから

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

26ページと27ページ

McCabeによるCCの元のバージョンはフォールスルーケースを1としてカウントするため、答えは5です。

4
CodinCat

私が使用したコードメトリックツールは、フォールスルーケースであっても、各ケースを個別のブランチとしてカウントします。

しかし、これは恣意的な選択です。コードメトリックツールは、デフォルトで注意を怠る傾向があります。 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]);
}
4
Seth

正解は7です。switchステートメント内の各ケースは1としてカウントされるため、5 x 1 = 5です。ifは1としてカウントされます。elseは1としてカウントされます。したがって、1 +(5 x 1)+ 1 = 7です。

これをメソッドの本体としてカウントする場合、メソッドはストレートパスとしてカウントされるため、ccは8になります。

5は間違った答えなので、受け入れた答えを正しい答えに変更してください。

1
Marton Berecz