Венгерская нотация - это соглашение об именах идентификаторов в компьютерном программировании, в котором имя переменной или функции указывает ее намерение или вид, а в некоторых диалектах - ее тип. Исходная венгерская нотация использует намерение или вид в соглашении об именах и иногда называется Apps Hungarian, поскольку она стала популярной в подразделении Microsoft Apps при разработке Word, Excel и других приложений. Поскольку подразделение Microsoft Windows приняло соглашение об именах, они использовали для именования фактический тип данных, и это соглашение стало широко распространяться через Windows API; это иногда называют системной венгерской нотацией.
Симони:... BCPL [имел] единственный тип, который был 16-битным словом... не то чтобы это важно.
Буч: Если вы не продолжите венгерскую нотацию.
Симони: Совершенно верно... мы тоже перешли к типизированным языкам позже... Но... мы бы посмотрели на одно имя, и я бы вам много о нем рассказал...
Венгерская нотация была разработана так, чтобы быть независимой от языка, и впервые широко использовалась в языке программирования BCPL. Поскольку BCPL не имеет типов данных, кроме машинного слова, ничто в самом языке не помогает программисту запоминать типы переменных. Венгерская нотация призвана исправить это, предоставляя программисту явное знание типа данных каждой переменной.
В венгерской нотации имя переменной начинается с группы строчных букв, которые являются мнемоникой для типа или назначения этой переменной, за которыми следует любое имя, выбранное программистом; эту последнюю часть иногда называют именем. Первый символ данного имени может быть написан с заглавной буквы, чтобы отделить его от индикаторов типа (см. Также CamelCase ). В противном случае регистр этого символа обозначает область действия.
Оригинальная венгерская нотация, которая теперь будет называться Apps Hungarian, была изобретена Чарльзом Симони, программистом, который работал в Xerox PARC около 1972–1981 годов и позже стал главным архитектором Microsoft.
Название обозначения является ссылкой на страну происхождения Симони; Имена венгерских людей «перевернуты» по сравнению с большинством других европейских имен; фамилия предшествует имени. Например, англоязычное имя «Чарльз Симони» на венгерском языке изначально было «Симони Карой». Точно так же имя типа предшествует «заданному имени» в венгерской нотации, а не стилю именования типа «последний» в Smalltalk (например, aPoint и lastPoint). Последний стиль именования был наиболее распространен в Xerox PARC во время пребывания там Симони.
Название Apps Hungarian было изобретено с тех пор, как это соглашение использовалось в подразделении приложений Microsoft. Системы Hungarian разработаны позже в команде разработчиков Microsoft Windows. В статье Симони упоминаются префиксы, используемые для обозначения «типа» хранимой информации. Его предложение было в значительной степени связано с украшением имен идентификаторов на основе семантической информации о том, что они хранят (другими словами, цели переменной), в соответствии с Apps Hungarian. Однако его предложения не были полностью отличны от того, что стало известно как Системный Венгерский, поскольку некоторые из предложенных им префиксов содержат мало или совсем не содержат семантической информации (см. Примеры ниже).
Обозначения систем и приложений различаются по назначению префиксов.
В системной венгерской нотации префикс кодирует фактический тип данных переменной. Например:
lAccountNum
: переменная - длинное целое число ( "l"
);arru8NumberList
: Переменная обр ау из U nsigned 8 -разрядных целых чисел ();"arru8"
bReadLine(bPort,amp;arru8NumberList)
: функция с байтовым кодом возврата.strName
: Variable представляет строку ( "str"
), содержащую имя, но не указывает, как эта строка реализована.Венгерская нотация приложений стремится кодировать логический тип данных, а не физический тип данных; таким образом, он дает намек на то, какова цель переменной или что она представляет.
rwPosition
: переменная представляет собой строку ( "rw"
);usName
: переменная представляет собой небезопасную строку ( "us"
), которую необходимо «продезинфицировать» перед использованием (например, см. « Внедрение кода» и « Межсайтовый скриптинг» для примеров атак, которые могут быть вызваны использованием необработанного пользовательского ввода)szName
: Переменный является Z АССА прекращается с Трингом ( "sz"
); это была одна из оригинальных приставок, предложенных Симони.Большинство, но не все, из предложенных Simonyi приставок имеют семантическую природу. Современному человеку кажется, что некоторые префиксы представляют физические типы данных, например, sz
для строк. Однако такие префиксы все еще были семантическими, поскольку Симони предназначал венгерскую нотацию для языков, системы типов которых не могли различать некоторые типы данных, которые современные языки принимают как должное.
Ниже приведены примеры из оригинальной статьи:
pX
указатель на другой тип X ; это содержит очень мало семантической информации.d
префикс, означающий разницу между двумя значениями; например, dY может представлять расстояние по оси Y графика, в то время как переменная, только что названная y, может быть абсолютной позицией. Это полностью семантический характер.sz
представляет собой строку с нулевым или нулевым символом в конце. В C это содержит некоторую семантическую информацию, поскольку неясно, является ли переменная типа char * указателем на одиночный символ, массив символов или строку с нулевым символом в конце.w
отмечает переменную, которая является словом. Он практически не содержит семантической информации и, вероятно, будет считаться системным венгерским.b
отмечает байт, который, в отличие от w, может иметь семантическую информацию, потому что в C единственным типом данных байтового размера является char, поэтому они иногда используются для хранения числовых значений. Этот префикс может устранить двусмысленность между тем, содержит ли переменная значение, которое следует рассматривать как символ или число.Хотя в обозначениях всегда используются начальные строчные буквы в качестве мнемоники, они не предписывают сами мнемонические символы. Существует несколько широко используемых соглашений (см. Примеры ниже), но можно использовать любой набор букв, если они согласованы в рамках заданного кода.
Код, использующий венгерскую нотацию приложений, может иногда содержать венгерские системы при описании переменных, которые определяются исключительно в терминах их типа.
В некоторых языках программирования аналогичные обозначения, которые теперь называются сигилами, встроены в язык и применяются компилятором. Например, в некоторых формах BASIC, name$
имена в строку и count%
имена целого. Основное различие между венгерской нотацией и сигилами состоит в том, что сигилы объявляют тип переменной на языке, тогда как венгерская нотация представляет собой чисто схему именования, не влияющую на машинную интерпретацию текста программы.
bBusy
: boolean chInitial
: char cApples
: количество предметовdwLightYears
: двойное слово (Системы)fBusy
: flag (или float )nSize
: целое число (системы) или счетчик (приложения)iSize
: целое число (системы) или индекс (приложения)fpPrice
: с плавающей точкой db Pi
: double (Системы)p Foo
: указатель rgStudents
: массив или диапазонszLastName
: строка с нулевым символом в концеu16Identifier
: 16-разрядное целое число без знака (Системы)u32Identifier
: 32-битное целое число без знака (Системы)stTime
: структура времени часовfnFunction
: имя функцииЗа мнемоникой указателей и массивов, которые не являются фактическими типами данных, обычно следует тип самого элемента данных:
pszOwner
: указатель на строку с нулевым символом в концеrgfpBalances
: Массив с плавающей запятой значенийaulColors
: массив беззнаковых длинных (Системы)Хотя венгерская нотация может применяться к любому языку программирования и среде, она была широко принята Microsoft для использования с языком C, в частности для Microsoft Windows, и ее использование по-прежнему в значительной степени ограничено этой областью. В частности, использование венгерской нотации широко евангелизировал по Чарльз Петцольд «s „Программирование Windows“, в оригинале (и для многих читателей, окончательная) книга по Windows API, программирование. Таким образом, многие часто встречающиеся конструкции венгерской нотации специфичны для Windows:
wParam
(параметр размера слова) и lParam
(параметр длинного целого числа) для функции WindowProc ().hwndFoo
: дескриптор окнаlpszBar
: длинный указатель на строку с нулевым символом в концеВ C ++ нотация иногда расширяется, чтобы включить область видимости переменной, необязательно разделенную подчеркиванием. Это расширение также часто используется без венгерской спецификации типа:
g_nWheels
: член глобального пространства имен, целое числоm_nWheels
: член структуры / класса, целое числоm_wheels
, _wheels
: член структуры / классаs_wheels
: статический член классаc_wheels
: статический член функцииВ коде JavaScript, использующем jQuery, $
префикс часто используется для обозначения того, что переменная содержит объект jQuery (а не простой объект DOM или какое-либо другое значение).
(Некоторые из них применимы только к Systems Hungarian.)
Сторонники утверждают, что преимущества венгерской нотации включают:
btn
может найти все объекты Button.Большинство аргументов против венгерской нотации - против системной венгерской нотации, а не венгерской нотации приложений. Некоторые потенциальные проблемы:
a_crszkvc30LastNameCol
: аргумент постоянной ссылки, содержащий содержимое столбца базы данных типа varchar (30), который является частью первичного ключа таблицы. LastName
... в настоящее время HN и другие формы кодирования типов просто препятствия. Они затрудняют изменение имени или типа переменной, функции, члена или класса. Они затрудняют чтение кода. И они создают возможность того, что система кодирования введет читателя в заблуждение.
Кодирование типа функции в имени (так называемая венгерская нотация) является повреждением мозга - компилятор в любом случае знает типы и может их проверить, и это только сбивает программиста с толку.
Хотя венгерское соглашение об именах больше не широко используется, основная идея стандартизации кратких и точных сокращений по-прежнему имеет значение. Стандартизированные префиксы позволяют точно проверять типы, когда вы используете абстрактные типы данных, которые ваш компилятор не может обязательно проверить.
Нет, я не рекомендую «венгерский». Я рассматриваю венгерский (встраивание сокращенной версии типа в имя переменной) как метод, который может быть полезен в нетипизированных языках, но совершенно не подходит для языка, поддерживающего универсальное программирование и объектно-ориентированное программирование - оба из которых подчеркивают выбор операций на основе типа и аргументов (известных языку или поддержке времени выполнения). В этом случае «встраивание типа объекта в имена» просто усложняет и минимизирует абстракцию.
Если вы внимательно читаете статью Симони, то он имел в виду то же соглашение об именах, которое я использовал в моем примере выше, где мы решили, что это us
означает небезопасную строку и s
означает безопасную строку. Они оба типа string
. Компилятор не поможет вам, если вы назначите одно другому, а Intellisense [ интеллектуальная система завершения кода ] не скажет вам bupkis. Но они семантически разные. Они должны интерпретироваться по-разному и обрабатываться по-разному, и необходимо будет вызвать какую-то функцию преобразования, если вы назначите одну другому, или у вас возникнет ошибка во время выполнения. Если вам повезет. У Apps Hungarian по-прежнему огромная ценность, поскольку они увеличивают коллокацию в коде, что упрощает чтение, запись, отладку и поддержку кода и, что наиболее важно, делает неправильный код неправильным.... (Системы Венгерский) было тонким, но полным непониманием намерений и практики Симони.