Венгерская нотация - это соглашение об именах идентификаторов в компьютерном программировании , в котором имя переменной или функции указывает ее намерение или вид, а в некоторых диалектах - ее тип . Оригинальная венгерская нотация использует намерение или вид в своем соглашении об именах и иногда называется венгерскими приложениями, поскольку она стала популярной в подразделении Microsoft Apps при разработке Word, Excel и других приложений. Поскольку подразделение Microsoft Windows приняло соглашение об именах, они использовали для именования фактический тип данных, и это соглашение стало широко распространяться через Windows API; это иногда называют Системной венгерской нотацией.
Буч : Если вы не продолжите венгерскую нотацию.
Симони : Совершенно верно ... мы тоже перешли к типизированным языкам позже ... Но ... мы бы посмотрели на одно имя, и я бы вам рассказал о нем много ... [1]Венгерская нотация была разработана так, чтобы быть независимой от языка, и впервые широко использовалась в языке программирования 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,&arru8NumberList)
: функция с байтовым кодом возврата.strName
: Variable представляет строку ("str"
), содержащую имя, но не указывает, как эта строка реализована.
Венгерская нотация приложений стремится кодировать логический тип данных, а не физический тип данных; таким образом, он дает намек на то, какова цель переменной или что она представляет.
rwPosition
: переменная представляет собой строку ("rw"
);usName
: переменная представляет собой небезопасную строку ("us"
), которую необходимо «продезинфицировать» перед использованием (например, см. внедрение кода и межсайтовые сценарии для примеров атак, которые могут быть вызваны использованием необработанного пользовательского ввода)szName
: Переменный является Z АССА прекращается с Трингом ("sz"
); это была одна из оригинальных приставок, предложенных Симони.
Большинство, но не все, из предложенных Simonyi приставок имеют семантическую природу. Современному человеку кажется, что некоторые префиксы представляют физические типы данных, например, sz
для строк. Однако такие префиксы все еще были семантическими, поскольку Симони предназначал венгерскую нотацию для языков, системы типов которых не могли различать некоторые типы данных, которые современные языки принимают как должное.
Ниже приведены примеры из оригинальной статьи: [2]
pX
указатель на другой тип X ; это содержит очень мало семантической информации.d
префикс, означающий разницу между двумя значениями; например, dY может представлять расстояние по оси Y графика, в то время как переменная, только что названная y, может быть абсолютной позицией. Это полностью семантический характер.sz
- строка с нулевым или нулевым символом в конце. В C это содержит некоторую семантическую информацию, поскольку неясно, является ли переменная типа char * указателем на одиночный символ, массив символов или строку с нулевым символом в конце.w
отмечает переменную, которая является словом. Он практически не содержит семантической информации и, вероятно, будет считаться системным венгерским.b
отмечает байт, который, в отличие от w, может иметь семантическую информацию, потому что в C единственным байтовым типом данных является char , поэтому они иногда используются для хранения числовых значений. Этот префикс может устранить двусмысленность между тем, содержит ли переменная значение, которое следует рассматривать как символ или число.
Хотя в обозначении всегда используются начальные строчные буквы в качестве мнемоники, они не предписывают сами мнемонические символы. Существует несколько широко используемых соглашений (см. Примеры ниже), но можно использовать любой набор букв, если они согласованы в рамках заданного кода.
Код, использующий венгерскую нотацию приложений, может иногда содержать венгерские системы при описании переменных, которые определяются исключительно в терминах их типа.
Отношение к сигилам
В некоторых языках программирования аналогичные обозначения, которые теперь называются сигилами , встроены в язык и применяются компилятором. Например, в некоторых формах BASIC , name$
имена в строку и count%
имена целого . Основное различие между венгерской нотацией и сигилами состоит в том, что сигилы объявляют тип переменной на языке, тогда как венгерская нотация представляет собой чисто схему именования, не влияющую на машинную интерпретацию текста программы.
Примеры
bBusy
: booleanchInitial
: charcApples
: количество предметовdwLightYears
: двойное слово (Системы)fBusy
: flag (или float )nSize
: целое число (системы) или счетчик (приложения)iSize
: целое число (системы) или индекс (приложения)fpPrice
: с плавающей точкойdbPi
: double (Системы)pFoo
: указательrgStudents
: массив или диапазонszLastName
: строка с нулевым завершениемu16Identifier
: 16-разрядное целое число без знака (Системы)u32Identifier
: 32-битное целое число без знака (Системы)stTime
: структура времени часовfnFunction
: имя функции
За мнемоникой указателей и массивов , которые не являются фактическими типами данных, обычно следует тип самого элемента данных:
pszOwner
: указатель на строку с нулевым символом в концеrgfpBalances
: Массив с плавающей запятой значенийaulColors
: массив беззнаковых длинных (Системы)
Хотя венгерская нотация может применяться к любому языку программирования и среде, она была широко принята Microsoft для использования с языком C, в частности для Microsoft Windows , и ее использование по-прежнему в значительной степени ограничено этой областью. В частности, использование венгерской нотации широко евангелизировал по Чарльз Петцольд «s „Программирование Windows“ , в оригинале (и для многих читателей, окончательная) книга по Windows API , программирование. Таким образом, многие часто встречающиеся конструкции венгерской нотации специфичны для Windows:
- Для программистов, которые изучили программирование Windows на C, вероятно, наиболее запоминающимися примерами являются
wParam
(параметр размера слова) иlParam
(параметр длинного целого числа) для функции WindowProc (). hwndFoo
: дескриптор окнаlpszBar
: длинный указатель на строку с нулевым символом в конце
В C ++ нотация иногда расширяется, чтобы включить область видимости переменной, необязательно разделенную подчеркиванием. [3] [4] Это расширение часто также используется без венгерской спецификации типа:
g_nWheels
: член глобального пространства имен, целое числоm_nWheels
: член структуры / класса, целое числоm_wheels
,_wheels
: член структуры / классаs_wheels
: статический член классаc_wheels
: статический член функции
В коде JavaScript, использующем jQuery , $
префикс часто используется для обозначения того, что переменная содержит объект jQuery (а не простой объект DOM или какое-либо другое значение). [5]
Преимущества
(Некоторые из них относятся только к Systems Hungarian.)
Сторонники утверждают, что преимущества венгерской нотации включают: [2]
- Тип символа можно увидеть по его названию. Это полезно при просмотре кода вне интегрированной среды разработки - например, при просмотре кода или распечатке - или когда объявление символа находится в другом файле с точки использования, например функции.
- В языке, использующем динамическую типизацию или нетипизированном, украшения, относящиеся к типам, перестают быть избыточными. В таких языках переменные обычно не объявляются как содержащие данные определенного типа, поэтому единственным ключом к пониманию того, какие операции с ними можно выполнять, являются подсказки программиста, такие как схема именования переменных, документация и комментарии. Как упоминалось выше, на таком языке расширена венгерская нотация ( BCPL ).
- Форматирование имен переменных может упростить некоторые аспекты рефакторинга кода (в то же время делая другие аспекты более подверженными ошибкам).
- В блоке кода можно использовать несколько переменных с одинаковой семантикой: dwWidth, iWidth, fWidth, dWidth.
- Имена переменных можно легко запомнить, зная только их типы.
- Это приводит к более согласованным именам переменных.
- При чтении кода можно легко обнаружить несоответствующее приведение типов и операции с несовместимыми типами.
- В сложных программах с множеством глобальных объектов (VB / Delphi Forms) наличие базовой префиксной записи может облегчить работу по поиску компонента внутри редактора. Например, поиск строки
btn
может найти все объекты Button. - Применение венгерской нотации более узким способом, например применение только для переменных-членов , помогает избежать конфликта имен .
- Печатный код более понятен читателю в случае типов данных, преобразований типов, назначений, усечений и т. Д.
Недостатки
Большинство аргументов против венгерской нотации направлены против системной венгерской нотации, а не венгерской нотации приложений . Некоторые потенциальные проблемы:
- Венгерская нотация избыточна, когда проверка типов выполняется компилятором. Компиляторы для языков, обеспечивающих строгую проверку типов, таких как Pascal , обеспечивают автоматическое согласование использования переменной с ее типом; проверка на глаз является избыточной и возможна человеческая ошибка.
- Большинство современных интегрированных сред разработки отображают типы переменных по запросу и автоматически помечают операции, в которых используются несовместимые типы, что делает эту нотацию в значительной степени устаревшей.
- Венгерская нотация сбивает с толку, когда она используется для представления нескольких свойств, как в a_crszkvc30LastNameCol : постоянный ссылочный аргумент , содержащий содержимое столбца базы данных LastName типа varchar (30), который является частью первичного ключа таблицы .
- Это может привести к несогласованности при изменении или переносе кода. Если тип переменной изменяется, либо оформление имени переменной будет несовместимо с новым типом, либо имя переменной должно быть изменено. Особенно хорошо известен пример стандартного типа WPARAM и сопутствующего ему формального параметра wParam во многих объявлениях системных функций Windows. «W» означает «слово», где «слово» - это собственный размер слова аппаратной архитектуры платформы. Первоначально он был 16-битным типом для архитектур с 16-битным словом, но был изменен на 32-битный тип в 32-битных словарных архитектурах или 64-битный тип в 64-битных словесных архитектурах в более поздних версиях операционной системы, сохраняя исходное имя (его истинный базовый тип - UINT_PTR, то есть целое число без знака, достаточно большое, чтобы содержать указатель). Семантический импеданс и, следовательно, путаница и непоследовательность программистов от платформы к платформе, основаны на предположении, что «w» обозначает двухбайтовое 16-битное слово в этих различных средах.
- В большинстве случаев знание использования переменной подразумевает знание ее типа. Кроме того, если использование переменной неизвестно, ее нельзя определить по ее типу.
- Венгерская нотация снижает преимущества использования редакторов кода, поддерживающих завершение имен переменных, поскольку программист должен сначала ввести спецификатор типа, который с большей вероятностью столкнется с другими переменными, чем при использовании других схем именования.
- Это делает код менее читаемым, скрывая назначение переменной с помощью префиксов типа и области видимости. [6]
- Дополнительная информация о типе может недостаточно заменить более описательные имена. Например, sDatabase не сообщает читателю, что это такое. databaseName может быть более описательным именем.
- Когда имена достаточно информативны, дополнительная информация о типе может быть избыточной. Например, firstName, скорее всего, является строкой. Так что присвоение ему имени sFirstName только добавляет беспорядка в код.
- Имена запомнить сложнее.
- В блоке кода с похожими именами можно использовать несколько переменных с разной семантикой: dwTmp, iTmp, fTmp, dTmp .
- Размещение идентификаторов типа данных или символа намерения в качестве префикса к имени поля или переменной подрывает возможность в некоторых средах программирования переходить к имени поля или переменной в алфавитном порядке, когда пользователь начинает вводить имя. FileMaker [7], например, является одной из таких сред программирования. При использовании одной из этих программных сред может быть предпочтительнее вместо этого суффиксировать данные имена такими идентифицирующими символами.
Известные мнения
- Роберт Сесил Мартин (против венгерской нотации и всех других форм кодирования):
... в настоящее время HN и другие формы кодирования типов просто препятствия. Они затрудняют изменение имени или типа переменной, функции, члена или класса. Они затрудняют чтение кода. И они создают возможность того, что система кодирования введет читателя в заблуждение. [8]
- Линус Торвальдс (против Системного Венгерского):
Кодирование типа функции в имени (так называемая венгерская нотация) является повреждением мозга - компилятор в любом случае знает типы и может их проверить, и это только сбивает программиста с толку. [9]
- Стив МакКоннелл (для приложений на венгерском языке):
Хотя венгерское соглашение об именах больше не широко используется, основная идея стандартизации кратких и точных сокращений по-прежнему имеет значение. Стандартизированные префиксы позволяют точно проверять типы, когда вы используете абстрактные типы данных, которые ваш компилятор не может обязательно проверить. [10]
- Бьярне Страуструп (против системного венгерского языка за C ++):
Нет, я не рекомендую «венгерский». Я рассматриваю венгерский (встраивание сокращенной версии типа в имя переменной) как метод, который может быть полезен в нетипизированных языках, но совершенно не подходит для языка, поддерживающего универсальное программирование и объектно-ориентированное программирование - оба из которых подчеркивают выбор операций на основе типа и аргументов (известных языку или поддержке времени выполнения). В этом случае «встраивание типа объекта в имена» просто усложняет и минимизирует абстракцию. [11]
- Джоэл Спольски (для приложений на венгерском языке):
Если вы внимательно читаете статью Симони, то он имел в виду то же соглашение об именах, которое я использовал в моем примере выше, где мы решили, что это
us
означает небезопасную строку иs
означает безопасную строку. Они оба типаstring
. Компилятор не поможет вам, если вы назначите одно другому, а Intellisense [ интеллектуальная система завершения кода ] не скажет вам bupkis . Но они семантически разные. Они должны интерпретироваться по-разному и обрабатываться по-разному, и необходимо будет вызвать какую-то функцию преобразования, если вы назначите одну другому, или у вас возникнет ошибка во время выполнения. Если повезет. У Apps Hungarian по-прежнему огромная ценность, поскольку они увеличивают коллокацию в коде, что упрощает чтение, запись, отладку и сопровождение кода и, что наиболее важно, делает неправильный код неправильным .... (Системы Венгерский) было тонким, но полным непониманием намерений и практики Симони. [12] - Рекомендации Microsoft по дизайну [13] отговаривают разработчиков от использования системной венгерской нотации при выборе имен для элементов в библиотеках классов .NET, хотя это было обычным явлением на предыдущих платформах разработки Microsoft, таких как Visual Basic 6 и ранее. В этих Рекомендациях по проектированию ничего не говорится об именах для локальных переменных внутри функций.
Смотрите также
- Соглашение об именах Лешинского , венгерская нотация для разработки баз данных
- Польская нотация
- PascalCase
Рекомендации
- ^ "Устная история Чарльза Симони" (PDF) . Archive.computerhistory.org \ accessdate = 5 августа 2018 года .
- ^ а б Чарльз Симони (ноябрь 1999 г.). «Венгерская нотация» . Библиотека MSDN . Корпорация Майкрософт
- ^ «Стиль программирования Mozilla» . Developer.mozilla.org . Проверено 17 марта 2015 года .
- ^ «Рекомендации по стилю кодирования Webkit» . Webkit.org . Проверено 17 марта 2015 года .
- ^ «Почему переменная JavaScript должна начинаться со знака доллара?» . Переполнение стека . Проверено 12 февраля +2016 .
- ^ Джонс, Дерек М. (2009). Новый стандарт C: Культурный и экономический комментарий (PDF) . Эддисон-Уэсли. п. 727. ISBN 978-0-201-70917-9.
- ^ «Создайте приложение для любой задачи - FileMaker - дочерняя компания Apple» . Filemaker.com . Проверено 5 августа 2018 .
- ^ Мартин, Роберт Сесил (2008). Чистый код: руководство по созданию гибкого программного обеспечения . Редмонд, Вашингтон: Prentice Hall, PTR. ISBN 978-0-13-235088-4.
- ^ «Стиль кодирования ядра Linux» . Документация ядра Linux . Проверено 9 марта 2018 .
- ^ МакКоннелл, Стив (2004). Код завершен (2-е изд.). Редмонд, Вашингтон: Microsoft Press . ISBN 0-7356-1967-0.
- ^ Страуструп, Бьярн (2007). "Часто задаваемые вопросы о стиле и технике C ++ Бьярна Страуструпа" . Проверено 15 февраля 2015 года .
- ^ Спольски, Джоэл (2005-05-11). «Сделать неправильный код неправильным» . Джоэл о программном обеспечении . Проверено 13 декабря 2005 .
- ^ «Рекомендации по проектированию для разработки библиотек классов: общие правила именования» . Проверено 3 января 2008 .
Внешние ссылки
- Мета-программирование: метод производства программного обеспечения Чарльз Симони, декабрь 1976 г. (докторская диссертация)
- Венгерская нотация - теперь моя очередь :) - WebLog Ларри Остермана
- Венгерская нотация (MSDN)
- HTML-версия статьи Дуга Клундера
- Соглашения об именах RVBA
- Соглашения о стилях кодирования (MSDN)