c – 实施Halstead复杂度指标的问题

我目前正在练习一个简单的程序来理解从Halstead的软件科学中获得各种指标所涉及的方程式.我相信我正确地做到了,但我觉得我没有注册所有操作数和操作符,所以我可以从数学开始.

我正在使用的程序是:

/*01*/ // counts how many items in sArray[] are also in tArray[]
/*02*/ int matched(int sArray[], int tArray[], int sMax, int tMax)
/*03*/ {
/*04*/    int count, i, first, middle, last;
/*05*/ 
/*06*/    for (i = 0; i < sMax; ++i)
/*07*/    {
/*08*/        last = tMax - 1;
/*09*/        for (int first = 0; first <= last;)
/*10*/        {
/*11*/            middle = (first + last) / 2;
/*12*/            if (tArray[middle] == sArray[i])
/*13*/            {
/*14*/                 count++;
/*15*/                 break;
/*16*/            } 
/*17*/            if (tArray[middle] < sArray[i]) 
/*18*/            {
/*19*/                 first = middle + 1;
/*20*/            }
/*21*/            else
/*22*/            {
/*23*/                 last =  middle - 1;
/*24*/            }
/*25*/         }
/*26*/    }
/*27*/    return count;
/*28*/ }

而且我已经出来了

> n1 =不同运算符的数量= 10
> n2 =不同操作数的数量= 9
> N1 =操作符总数= 24
> N2 =操作数总数= 34

这些注释显示了发现的不同运算符和操作数:

Operators
= Assignment (line 6, 8, 9, 11, 19, 23) = 6
< Less Than (line 6, 17) = 2
++ Increment (line 6, 14) = 2
– Subtract (line 8, 23) = 2
<= Less Than or Equal to (line 9) = 1
+ Addition (line 11, 19) = 2
/ Division (line 11) = 1
== Equal to (line 12) = 1
[] index (line 2*2, 12*2, 17*2 = 6
break (line 15) = 1

Operands
count (line 4, 14) = 2
i (line 4, 6*3, 12, 17) = 6
first (line 4, 9*2, 11, 19) = 5
middle (line 4, 11, 12, 17, 19, 23) = 6
last (line 4, 8, 9, 11, 23) = 5
sArray (line
2, 12, 17) = 3
tArray (line 2, 12, 17) = 3
sMax (line 2, 6)
= 2
tMax (line 2, 8) = 2

有什么重要的我错过了吗?根据我的理解:

>操作数是值
>运算符操纵和检查操作数

最佳答案 Halstead指标的要点是回答很多问题,例如“代码阅读有多难”,“编写代码需要付出多少努力”等等.Halstead难度指标的公式应该提供一个暗示如何第一个问题回答:

Difficulty = (Unique Operators / 2) * (Operands / Unique Operands);

您可以看到,拥有更多独特的运算符显然会使代码更难以阅读.

关于大括号:关于这个主题的很多来源都认为{}是运算符,我没有看到它的意义.卷曲大括号充当结构(标点符号)元素,并且在很多方面使代码更容易理解,而不是更难. (以带有和不带括号的条件块为例)

计算匹配的函数名称仅在更一般的上下文中相关,但在测量函数实现的度量时则不相关(假设没有递归).

关于运算符:计算运算符可能很棘手.例如,函数声明中出现的[]和第12行和第17行的[]实际上是不同的东西.第一个是数组声明,第二个是operator [] – 按索引访问元素.与后缀和前缀相同,在程序中同时使用它们会使其更难阅读.

同样的逻辑适用于语言关键字:for,if,else,break,return.代码越多,阅读越难.

在类型上:变量声明中的类型名称也很棘手.有些将它们归于运算符,有些归属于操作数.但是,如果我们再次查看“难度”公式,我们会看到类型名称更适合运算符,因为在代码中使用更多不同类型会使其更难阅读,而不是更容易.

你对操作数的计数似乎没问题.

Operators 
= Assignment (line 6, 8, 9, 11, 19, 23) = 6 
< Less Than (line 6, 17) = 2 
++ Prefix Increment (line 6) = 1
++ Postfix Increment (line 14) = 1 
- Subtract (line 8, 23) = 2 
<= Less Than or Equal to (line 9) = 1 
+ Addition (line 11, 19) = 2 
/ Division (line 11) = 1 
== Equal to (line 12) = 1
[] declaration (line 2) = 2 
[] index (line 12, 17) = 4
for (line 6, 9) = 2
if (line 12, 17) = 2
else (line 21) = 1
break (line 15) = 1
return (line 27) = 1
int declaration = 7

Operands 
count (line 4, 14) = 2 
i (line 4, 6*3, 12, 17) = 6 
first (line 4, 9*2, 11, 19) = 5 
middle (line 4, 11, 12, 17, 19, 23) = 6 
last (line 4, 8, 9, 11, 23) = 5 
sArray (line 2, 12, 17) = 3 
tArray (line 2, 12, 17) = 3 
sMax (line 2, 6) = 2 
tMax (line 2, 8) = 2

Metrics
n1 = 17
n2 = 9
N1 = 37
N2 = 34
Difficulty = (n1 * N2) / (2 * n2) = 32.1

我指的是Wikithis page on Virtual Machinery.

顺便说一句,大多数事情都是我的看法,可能与更多官方消息来源不符.

顺便说一下:2,这里是对C代码中应该算作运算符和操作数的严格定义:http://www.verifysoft.com/en_halstead_metrics.html.

点赞