Проблемы реализации показателей сложности Халстеда
В настоящее время я практикуюсь с простой программой, чтобы понять уравнения, связанные с получением различных метрик из программного обеспечения Халстеда. Я верю, что делаю это правильно, но мне кажется, что я не зарегистрировал все операнды и операторы, чтобы начать с математики.
Программа, которую я использую:
/*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
разрыв (линия 15) = 1Операнды
граф (строка 4, 14) = 2
i (строка 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
Саррей (линия 2, 12, 17) = 3
tArray (линия 2, 12, 17) = 3
ѕмакс (линия 2, 6) = 2
tMax (строка 2, 8) = 2
Является есть что-нибудь жизненно важное, что я упустил? Из моего понимания:
- операнды - это значения
- операторы манипулируют и проверяют операнды
2 ответа:
Суть метрик Холстеда состоит в том, чтобы ответить на множество вопросов, таких как "насколько трудно читать код", "сколько усилий было затрачено на написание кода" и т. д. Формула для метрики сложности Холстеда должна дать подсказку о том, как ответить на первый вопрос:
Вы можете видеть, что наличие большего количества уникальных операторов, очевидно, затрудняет чтение кода.Difficulty = (Unique Operators / 2) * (Operands / Unique Operands);
На фигурных скобках: многие источники по этому вопросу считают
{}
операторами, в которых я не вижу смысла от. Фигурные скобки выступают в качестве структурного (пунктуационного) элемента и во многом облегчают понимание кода, а не усложняют его. (Возьмем, к примеру, условный блок с фигурными скобками и без них)Подсчет имени функции
matched
уместен только в более общем контексте, но не при измерении метрик реализации функции (учитывая отсутствие рекурсии).О операторах: подсчет операторов может быть сложным. Например,
[]
, появляющиеся в объявлении функции и[]
в строках 12 и 17 на самом деле разные вещи. Первый-объявление массива, второй -operator[]
- обращение к элементу по индексу. То же самое с postfix и prefix++
, наличие их обоих в программе затрудняет чтение.Та же логика применима и к ключевым словам языка:
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 и далее операторы не значения их переменных.
Книга, на которую я ссылаюсь, - это программные метрики и программная Метрология Алена Абрана. Вы можете скачать его отсюда - > http://profs.etsmtl.ca/aabran/English/Accueil/ChapersBook/Abran%20-%20Chapter%20005.pdf Я надеюсь, что это разрешит все ваши сомнения.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
И имена функций, фигурные скобки, имена типов, все другие ключевые слова и все другие известные операторы подпадают под оператор раздел
Переменные и постоянные значения, которые вводятся в любые функции или операторы, являются операндами. Поэтому я и пришел к такому ответу.