【问题标题】:Issues Implementing Halstead's Complexity Metrics实施 Halstead 复杂性度量的问题
【发布时间】:2015-06-09 08:36:17
【问题描述】:

我目前正在练习一个简单的程序,以了解从 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

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

运营商
= 赋值(第 6、8、9、11、19、23 行)= 6
++ 增量(第 6、14 行)= 2
- 减去(第 8、23 行)= 2
+ 加法(第 11、19 行)= 2
/ 除法(第 11 行)= 1
== 等于(第 12 行)= 1
[] 索引(第 2*2、12*2、17*2 = 6
break(第 15 行)= 1

操作数
count (line 4, 14) = 2
i (line 4, 6*3, 12, 17) = 6
first (line 4, 9 *2, 11, 19) = 5
中间(第 4, 11, 12, 17, 19, 23 行)= 6
最后(第 4, 8, 9, 11, 23 行)= 5
sArray(行 2, 12, 17) = 3
tArray (第 2, 12, 17 行) = 3
sMax (第 2, 6 行) = 2
tMax(第 2、8 行)= 2

我错过了什么重要的事情吗?据我了解:

  1. 操作数是值
  2. 操作员操作和检查操作数

【问题讨论】:

  • 请不要在代码 sn-ps 中输入行号。如果您想引起对特定行的注意,请输入例如对该行的评论。
  • @JoachimPileborg 在这个问题的上下文中,将行号链接到它下面的注释更合理。不期望读者执行代码,它是为了软件测试找到运算符和操作数的数量,所以对于这个问题,我觉得它有助于读者快速轻松地浏览它,无论是评论还是评论。我认为您没有完整阅读这个问题,这没有任何区别,
  • 我不知道这些指标,但是前增量和后增量被认为是相同还是不同?两者都有。
  • 我不确定我是否诚实,这就是我正在努力解决的细节问题。我想他们会是不同的
  • 我很惊讶没有找到第三类:流量控制,比如breakreturn。但是经过反思,我意识到return 可能有一个操作数,所以我可以看到这里(和其他地方)使用的两个类别指的是指示做什么的元素和指定对象的元素。我会冒另一条评论的风险:一个被重写以提取一些常用代码行作为函数的程序,尽管功能相同,但与原始代码的度量标准不同?

标签: c++ c metrics


【解决方案1】:

Halstead 指标的重点是回答很多问题,例如“阅读代码有多难”、“编写代码付出了多少努力”等。Halstead 难度指标的公式应该提供提示关于第一个问题是如何回答的:

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

您可以看到,拥有更多唯一运算符显然会使代码更难阅读。

关于大括号:很多关于这个主题的资料都认为{} 是运算符,我不明白这一点。花括号充当结构(标点符号)元素,在很多方面使代码更容易理解,而不是更难。 (以带和不带大括号的条件块为例)

计算函数名称matched 仅在更一般的上下文中相关,但在测量函数实现的指标时不相关(假设没有递归)。

关于运算符:计数运算符可能很棘手。例如,出现在函数声明中的[] 和出现在第12 行和第17 行的[] 实际上是不同的东西。第一个是数组声明,第二个是operator[] - 按索引访问元素。后缀和前缀++ 也是如此,将它们都放在程序中会更难阅读。

同样的逻辑也适用于语言关键字:forifelsebreakreturn。代码中的它们越多,就越难阅读。

关于类型:变量声明中的类型名称也很棘手。有些将它们归因于运算符,有些则归因于操作数。但是,如果我们再次查看难度公式,我们会发现类型名称最好使用运算符,因为在代码中拥有更多不同类型会使其更难阅读,而不是更容易。

您的操作数计数似乎没问题。

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

【讨论】:

  • 很好地澄清了我对运算符的困惑以及我认为我对操作数的了解,写得也很好,谢谢。
【解决方案2】:

首先,将 count 初始化为 0,next 运算符不是值而是变量。

operators 
matched -1
() -6
[] -6
{} -6
int -7
for -2
if -2
else -1
return -1
= -6 
< -2
<= -1
++ -2
- -2
+ -2
/ -1
== -1
break -1

operands
2 -line no. 11 -1
1 (8,19,23) -3
0 -1
count -3
i -6
first -5
middle -6
last -5
sArray -3
tArray -3
sMax -2
tMax -2

N1=50
N2=40
n1=18
n2=12

我所指的书是 Alain Abran 所著的 Software Metrics and Software Metrology。 你可以从这里下载 -> http://profs.etsmtl.ca/aabran/English/Accueil/ChapersBook/Abran%20-%20Chapter%20005.pdf

我希望它能解决你所有的疑惑。

函数名称、大括号、类型名称、所有其他关键字和所有其他众所周知的运算符都在运算符部分

输入到任何函数或运算符的变量和常量值都是操作数。

因此,我想出了这个答案。

【讨论】:

  • 感谢您的回答,感谢您花时间在这里,但是您是否有更多信息说明为什么您会从任何可靠的来源获得结果?
  • 据我所知,函数大括号都是运算符,常量数字或字符都是操作数,这并不意味着它们只是运算符和操作数。
  • 我所指的书是 Alain Abran 的 Software Metrics and Software Metrology。
  • 对不起哥们,我不像以前那么活跃了。将您回复的 cmets 放入 answe 并为这本书的推荐 +1,我会读一读。
  • 是的,但是您需要以合理的方式将您编写的 cmets 添加到答案中,以便希望进一步查看的用户无需阅读 cmets 就可以理解,我不会给您 50如果您需要帮助,请参考到stackoverflow关于如何回答问题的指南。 stackoverflow.com/help/how-to-answer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
相关资源
最近更新 更多