В настоящее время я тренируюсь с простой программой, чтобы понять уравнения, связанные с выводом различных метрик из науки о программировании Холстеда. Я действительно считаю, что делаю это правильно, но мне кажется, что я не зарегистрировал все операнды и операторы, чтобы начать с математики.
Я использую программу:
/*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*/ }
И я вышел с
Эти примечания показывают различные найденные операторы и операнды:
операторы
= Назначение (строки 6, 8, 9, 11, 19, 23) = 6
< Меньше, чем (строка 6, 17) = 2
++ Инкремент (строка 6, 14) = 2
— Вычесть (строки 8, 23) = 2
<= Меньше или равно (строка 9) = 1
+ Сложение (строка 11, 19) = 2
/ Деление (строка 11) = 1
== равно (строка 12) = 1
[] индекс (строка 2 * 2, 12 * 2, 17 * 2 = 6
перерыв (строка 15) = 1Операнды
count (строка 4, 14) = 2
я (строка 4, 6 * 3, 12, 17) = 6
первый (строка 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
Есть ли что-то жизненно важное, что я пропустил? Из моего понимания:
Цель метрик Холстеда — ответить на множество вопросов, таких как «Насколько сложно читать код», «Сколько усилий было потрачено на написание кода» и т. Д. Формула для метрики «Трудность Холстеда» должна дать подсказку о том, как Ответ на первый вопрос:
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 а также эта страница на виртуальной машине.
Кстати, большинство сказанного — мое мнение, и может не совпадать с более официальными источниками.
Кстати: 2, вот точное и строгое определение того, что следует считать как операторы и операнды в коде C ++: http://www.verifysoft.com/en_halstead_metrics.html.
во-первых, инициализируйте счетчик до 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
Книга, на которую я ссылаюсь — «Метрики программного обеспечения и метрология программного обеспечения» Алена Абрана.
Вы можете скачать его здесь -> http://profs.etsmtl.ca/aabran/English/Accueil/ChapersBook/Abran%20-%20Chapter%20005.pdf
Я надеюсь, что это решит все ваши сомнения.
Имена функций, фигурные скобки, имена типов, все другие ключевые слова и все другие хорошо известные операторы попадают в раздел операторов
Переменные и постоянные значения, которые вводятся в любые функции или операторы, являются операндами.
Следовательно, я приду с этим ответом.