Венгерская нотация — это соглашение об именовании идентификаторов в компьютерном программировании , в котором имя переменной или функции указывает на ее намерение или вид, или в некоторых диалектах на ее тип . Первоначальная венгерская нотация использует только намерение или вид в своем соглашении об именовании и иногда называется Apps Hungary , поскольку она стала популярной в подразделении Microsoft Apps при разработке приложений Microsoft Office . Когда подразделение Microsoft Windows приняло соглашение об именовании, оно основывалось на фактическом типе данных, и это соглашение получило широкое распространение через Windows API ; иногда это называется системной венгерской нотацией.
Симони : ...BCPL [имел] единственный тип, который представлял собой 16-битное слово... не то чтобы это имело значение.
Буч : Если только вы не продолжите венгерскую нотацию.
Симони : Совершенно верно... позже мы перешли и к типизированным языкам... Но... мы бы посмотрели на одно имя, и я бы вам рассказал о нем очень много... [1]
Венгерская нотация была разработана как независимая от языка и нашла свое первое серьезное применение в языке программирования BCPL . Поскольку в BCPL нет других типов данных, кроме машинного слова , ничто в самом языке не помогает программисту запомнить типы переменных. Венгерская нотация направлена на исправление этого, предоставляя программисту явное знание типа данных каждой переменной.
В венгерской нотации имя переменной начинается с группы строчных букв, которые являются мнемоническими для типа или назначения этой переменной, за которыми следует любое имя, выбранное программистом; эта последняя часть иногда выделяется как заданное имя . Первый символ заданного имени может быть заглавным, чтобы отделить его от индикаторов типа (см. также CamelCase ). В противном случае регистр этого символа обозначает область действия.
Оригинальная венгерская нотация была изобретена Чарльзом Симони , программистом, работавшим в Xerox PARC примерно в 1972–1981 годах, и позже ставшим главным архитектором в Microsoft . Название нотации является ссылкой на страну происхождения Симони, а также, по словам Энди Херцфельда , потому что она делала программы «выглядящими так, как будто они были написаны на каком-то непостижимом иностранном языке». [2] Имена венгерских людей «перевернуты» по сравнению с большинством других европейских имен; фамилия предшествует имени . Например, англизированное имя «Charles Simonyi» на венгерском языке изначально было «Simonyi Károly». Точно так же имя типа предшествует «имени» в венгерской нотации. Похожий стиль именования Smalltalk «type last» (например, aPoint и lastPoint) был распространен в Xerox PARC во время пребывания там Симони. [ необходима цитата ]
В статье Симони о нотации упоминаются префиксы, используемые для указания «типа» хранимой информации. [3] [4] Его предложение было в значительной степени связано с декорированием имен идентификаторов на основе семантической информации о том, что они хранят (другими словами, назначение переменной ). Нотация Симони стала называться Apps hung, поскольку это соглашение использовалось в отделе приложений Microsoft. Systems hung была разработана позже в команде разработчиков Microsoft Windows . Apps hung не полностью отличается от того, что стало известно как Systems hung, поскольку некоторые из предложенных Симони префиксов содержат мало или вообще не содержат семантической информации (см. примеры ниже). [4]
Различие в нотации Systems и нотации Apps заключается в назначении префиксов.
В нотации Systems Hungary префикс кодирует фактический тип данных переменной. Например:
lAccountNum
: переменная — длинное целое число ( "l"
);arru8NumberList
: переменная представляет собой массив беззнаковых 8 - битных целых чисел ( ) "arru8"
;bReadLine(bPort,&arru8NumberList)
: функция с кодом возврата байтового значения.strName
: Переменная представляет собой строку ( "str"
), содержащую имя, но не определяет, как эта строка реализована.Венгерская нотация приложений стремится кодировать логический тип данных, а не физический; таким образом, она дает подсказку о назначении переменной или о том, что она представляет.
rwPosition
: переменная представляет строку ( "rw"
);usName
: переменная представляет собой небезопасную строку ( "us"
), которую необходимо «очистить» перед использованием (например, см. примеры атак, которые могут быть вызваны использованием необработанного пользовательского ввода, в разделах « Внедрение кода» и «Межсайтовый скриптинг» ).szName
: переменная — это строка , заканчивающаяся нулем ( ) "sz"
; это был один из первоначально предложенных Симони префиксов.Большинство, но не все, префиксы, предложенные Симони, имеют семантическую природу. Современному глазу некоторые префиксы кажутся представляющими физические типы данных, например, sz
для строк. Однако такие префиксы все еще были семантическими, поскольку Симони предназначал венгерскую нотацию для языков, системы типов которых не могли различать некоторые типы данных, которые современные языки принимают как должное.
Ниже приведены примеры из оригинальной статьи: [3]
pX
является указателем на другой тип X ; он содержит очень мало семантической информации.d
— это префикс, означающий разницу между двумя значениями; например, dY может представлять расстояние по оси Y графика, в то время как переменная, просто называемая y, может быть абсолютной позицией. Это полностью семантическое явление.sz
является строкой с нулевым или нулевым завершением. В языке C это содержит некоторую семантическую информацию, поскольку неясно, является ли переменная типа char* указателем на один символ, массив символов или строку с нулевым завершением.w
обозначает переменную, которая является словом. Это по сути не содержит никакой семантической информации и, вероятно, будет считаться системным венгерским.b
обозначает байт, который в отличие от w может иметь семантическую информацию, поскольку в C единственным типом данных размером в байт является char , поэтому они иногда используются для хранения числовых значений. Этот префикс может устранить неоднозначность между тем, содержит ли переменная значение, которое следует рассматривать как символ или число.Хотя нотация всегда использует начальные строчные буквы в качестве мнемоники, она не предписывает сами мнемоники. Существует несколько широко используемых соглашений (см. примеры ниже), но можно использовать любой набор букв, если они согласованы в пределах данного блока кода.
Код, использующий венгерскую нотацию Apps, иногда может содержать венгерскую нотацию Systems при описании переменных, которые определены исключительно в терминах их типа.
В некоторых языках программирования похожая нотация, которая теперь называется сигилы , встроена в язык и применяется компилятором. Например, в некоторых формах BASIC , name$
именует строку и count%
именует целое число . Основное различие между венгерской нотацией и сигилы заключается в том, что сигилы объявляют тип переменной в языке, тогда как венгерская нотация — это просто схема именования, не влияющая на машинную интерпретацию текста программы.
bBusy
: БулевоchInitial
: символcApples
: количество элементовdwLightYears
: двойное слово (Системы)fBusy
: флаг (или плавающий )nSize
: целое число (системы) или количество (приложения)iSize
: целое число (системы) или индекс (приложения)fpPrice
: с плавающей точкойdecPrice
: десятичныйdbPi
: двойной (Системы)pFoo
: указательrgStudents
: массив или диапазонszLastName
: строка с нулевым окончаниемu16Identifier
: беззнаковое 16-битное целое число (системы)u32Identifier
: беззнаковое 32-битное целое число (системы)stTime
: структура времени часовfnFunction
: имя функцииМнемоники для указателей и массивов , которые не являются фактическими типами данных, обычно сопровождаются типом самого элемента данных:
pszOwner
: указатель на строку, завершающуюся нулемrgfpBalances
: массив значений с плавающей точкойaulColors
: массив беззнаковых длинных чисел (системы)Хотя венгерская нотация может применяться к любому языку программирования и среде, она была широко принята корпорацией Microsoft для использования с языком C, в частности, для Microsoft Windows , и ее использование в значительной степени ограничено этой областью. В частности, использование венгерской нотации было широко пропагандировано в книге Чарльза Петцольда " Программирование Windows" , оригинальной (и для многих читателей окончательной) книге по программированию Windows API . Таким образом, многие часто встречающиеся конструкции венгерской нотации специфичны для Windows:
wParam
(параметр размера слова) и lParam
(параметр длинного целого числа) для функции WindowProc ().hwndFoo
: дескриптор окнаlpszBar
: длинный указатель на строку, заканчивающуюся нулемВ C++ эта нотация иногда расширяется, чтобы включить область действия переменной, опционально разделенную подчеркиванием. [5] [6] Это расширение часто также используется без венгерской спецификации типа:
g_nWheels
: член глобального пространства имен, целое числоm_nWheels
: член структуры/класса, целое числоm_wheels
, _wheels
: член структуры/классаs_wheels
: статический член классаc_wheels
: статический член функцииВ коде JavaScript, использующем jQuery , $
префикс часто используется для указания того, что переменная содержит объект jQuery (а не простой объект DOM или какое-либо другое значение). [7]
(Некоторые из них применимы только к системам венгерского языка.)
Сторонники утверждают, что преимущества венгерской нотации включают в себя: [3]
btn
может найти все объекты Button.Большинство аргументов против венгерской нотации направлены против нотации Systems hungary, а не Apps hungary [ требуется ссылка ] . Вот некоторые потенциальные проблемы:
a_crszkvc30LastNameCol
: константный ссылочный аргумент , содержащий содержимое столбца базы данныхLastName
типа varchar (30), который является частью первичного ключа таблицы .... в настоящее время HN и другие формы кодирования типов являются просто помехами. Они затрудняют изменение имени или типа переменной, функции, члена или класса. Они затрудняют чтение кода. И они создают возможность того, что система кодирования введет читателя в заблуждение. [10]
Кодирование типа функции в имени (так называемая венгерская нотация) — это ущербность для мозга, поскольку компилятор в любом случае знает типы и может их проверить, и это только запутывает программиста. [11]
Хотя венгерское соглашение об именовании больше не используется широко, основная идея стандартизации кратких, точных сокращений продолжает иметь значение. Стандартизированные префиксы позволяют вам точно проверять типы, когда вы используете абстрактные типы данных, которые ваш компилятор не обязательно может проверить. [12]
Нет, я не рекомендую «венгерский». Я рассматриваю «венгерский» (встраивание сокращенной версии типа в имя переменной) как технику, которая может быть полезна в нетипизированных языках, но совершенно не подходит для языка, поддерживающего обобщенное программирование и объектно-ориентированное программирование — оба из которых подчеркивают выбор операций на основе типа и аргументов (известных языку или поддержке времени выполнения). В этом случае «встраивание типа объекта в имена» просто усложняет и минимизирует абстракцию. [13]
Если вы внимательно прочтете статью Симони, то увидите, что он имел в виду тот же тип соглашения об именовании, который я использовал в своем примере выше, где мы решили, что
us
означает небезопасную строку, аs
означает безопасную строку. Они оба типаstring
. Компилятор не поможет вам, если вы назначите одно другому, и Intellisense [ интеллектуальная система завершения кода ] не сообщит вам о bupkis. Но они семантически различны. Их нужно интерпретировать по-разному и обрабатывать по-разному, и нужно будет вызвать какую-то функцию преобразования, если вы назначите одно другому, иначе у вас будет ошибка во время выполнения. Если вам повезет. Apps hung по-прежнему имеет огромную ценность, поскольку он увеличивает коллокацию в коде, что упрощает чтение, написание, отладку и поддержку кода, и, что самое важное, он заставляет неправильный код выглядеть неправильным.... (Systems hung) было тонким, но полным непониманием намерения и практики Симони. [4]