I'm currently practicing with a simple program to understand the equations involved in deriving various metrics from Halstead's software science. I do believe I'm doing it correctly, but I feel like I haven't registered all operands and operators so that I can start with the mathematics.
The program I'm using is:
/*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*/ }
And I've come out with
- n1 = the number of distinct operators = 10
- n2 = the number of distinct operands = 9
- N1 = the total number of operators = 24
- N2 = the total number of operands = 34
These notes show the distinct operators and operands found:
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
Is there anything vital I've missed out? From my understanding:
- Operands are values
- Operators manipulate and check operands
The point of Halstead's metrics is to answer a lot of questions like "How difficult is the code to read", "How much effort was put into writing the code", etc. The formula for Halstead's Difficulty metric should provide a hint on how the first question answered:
You can see that having more unique operators, obviously, makes the code harder to read.
On braces: A lot of sources on the subject consider
{}
to be operators, which I don't see the point of. Curly braces act as a structure (punctuation) element and in a lot of ways makes code easier to understand, not harder. (Take, for example, conditional block with and without braces)Counting the function name
matched
is relevant only in a more general context, but not when you measure the metrics of the function implementation (given there is no recursion).On operators: counting operators can be tricky. For example,
[]
appearing in function declaration and[]
on lines 12 and 17, are actually different things. The first one is array declaration, the second isoperator[]
- accessing element by index. The same with postfix and prefix++
, having them both in the program makes it harder to read.The same logic applies to language keywords:
for
,if
,else
,break
,return
. The more of them in the code the harder it is to read.On types: type names in variable declaration is also tricky. Some attribute them to operators, some to operands. But if we look again at the Difficulty formula, we would see that type names would better go to operators, in the sense that having more different types in the code make it harder to read, not easier.
Your counts for operands seems to be alright.
I was referring to Wiki and this page on Virtual Machinery.
By the way, most things said are my opinion, and may not coincide with more official sources.
By the way: 2, here is exact and strict definition on what should be counted as operators and operands in a C++ code: http://www.verifysoft.com/en_halstead_metrics.html.