实施 Halstead 复杂性指标的问题
Issues Implementing Halstead's Complexity Metrics
我目前正在练习一个简单的程序,以理解从 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
我错过了什么重要的事情吗?据我了解:
- 操作数是值
- 操作员操纵和检查操作数
首先,将计数初始化为 0,接下来的运算符不是值,它们是变量。
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
希望能解决大家的疑惑
函数名称、大括号、类型名称、所有其他关键字和所有其他众所周知的运算符都在运算符部分
输入到任何函数或运算符的变量和常量值都是操作数。
因此,我想出了这个答案。
Halstead 指标的重点是回答很多问题,例如 "How difficult is the code to read"、"How much effort was put into writing the code" 等。Halstead 难度指标的公式应该提供有关如何回答第一个问题的提示:
Difficulty = (Unique Operators / 2) * (Operands / Unique Operands);
您可以看到,拥有更多独特的运算符显然会使代码更难阅读。
关于大括号:很多有关该主题的资料都认为 {}
是运算符,我不明白这一点。大括号充当结构(标点符号)元素,在很多方面使代码更易于理解,而不是更难。 (例如,带和不带大括号的条件块)
计算函数名称 matched
仅在更一般的上下文中相关,但在衡量函数实现的指标时则无关(假设没有递归)。
关于运算符:计算运算符可能很棘手。例如,函数声明中出现的[]
和第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
我指的是 Wiki and this page on Virtual Machinery。
顺便说一句,大部分内容都是我的观点,可能与更多官方消息不一致。
顺便提一下:2,这里是关于在 C++ 代码中什么应该算作运算符和操作数的准确和严格的定义:http://www.verifysoft.com/en_halstead_metrics.html.
我目前正在练习一个简单的程序,以理解从 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) = 1Operands
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
我错过了什么重要的事情吗?据我了解:
- 操作数是值
- 操作员操纵和检查操作数
首先,将计数初始化为 0,接下来的运算符不是值,它们是变量。
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
希望能解决大家的疑惑
函数名称、大括号、类型名称、所有其他关键字和所有其他众所周知的运算符都在运算符部分
输入到任何函数或运算符的变量和常量值都是操作数。
因此,我想出了这个答案。
Halstead 指标的重点是回答很多问题,例如 "How difficult is the code to read"、"How much effort was put into writing the code" 等。Halstead 难度指标的公式应该提供有关如何回答第一个问题的提示:
Difficulty = (Unique Operators / 2) * (Operands / Unique Operands);
您可以看到,拥有更多独特的运算符显然会使代码更难阅读。
关于大括号:很多有关该主题的资料都认为 {}
是运算符,我不明白这一点。大括号充当结构(标点符号)元素,在很多方面使代码更易于理解,而不是更难。 (例如,带和不带大括号的条件块)
计算函数名称 matched
仅在更一般的上下文中相关,但在衡量函数实现的指标时则无关(假设没有递归)。
关于运算符:计算运算符可能很棘手。例如,函数声明中出现的[]
和第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
我指的是 Wiki and this page on Virtual Machinery。
顺便说一句,大部分内容都是我的观点,可能与更多官方消息不一致。
顺便提一下:2,这里是关于在 C++ 代码中什么应该算作运算符和操作数的准确和严格的定义:http://www.verifysoft.com/en_halstead_metrics.html.