Cod*_*Cat 9 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");
}
Run Code Online (Sandbox Code Playgroud)
什么是CC?
我发现一个帖子说它是5,用这个图表

(边缘是17,而不是16,我认为这是一个错字)
它说我们只需要将案例0和案例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
Run Code Online (Sandbox Code Playgroud)
所以它应该是6
什么是正确的答案?
我真的很困惑,谢谢.
编辑:
现在我认为是 7.是,7
因为如果n大于5,则不执行任何操作并退出switch语句.
然后我们得到这个图:
现在E = 18
18 - 13 + 2 = 7
我对么..?
真的,真的,真的很困惑......
好的,我找到了答案。
来自 McCabe.com
http://www.mccabe.com/pdf/mccabe-nist235r.pdf
第 26 和 27 页
答案是 5,因为 McCabe 的原始版本 CC 将失败案例计为 1。
我使用过的代码度量工具将每个案例视为一个单独的分支,即使它是失败案例。
但这是一个随意的选择。默认情况下,代码度量工具倾向于谨慎行事。最终评估 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]);
}
Run Code Online (Sandbox Code Playgroud)