Венгерская нотация

Венгерская нотация — это соглашение об именах идентификаторов в компьютерном программировании , в котором имя переменной или функции указывает ее назначение или вид, а в некоторых диалектах — ее тип . Исходная венгерская нотация использует в соглашении об именах только намерение или вид и иногда называется Apps Венгерский, поскольку она стала популярной в подразделении Microsoft Apps при разработке приложений Microsoft Office . Когда подразделение Microsoft Windows приняло соглашение об именовании, оно основывалось на реальном типе данных, и это соглашение получило широкое распространение через Windows API ; иногда это называют системной венгерской нотацией.

Симони : ...BCPL [имеет] единственный тип, который представляет собой 16-битное слово... не то чтобы это имело значение.

Буч : Если только ты не продолжишь использовать венгерскую систему обозначений.

Симони : Абсолютно... к типизированным языкам мы тоже перешли позже... Но... мы бы посмотрели на одно имя, и я бы вам точно много о нём рассказал... [1]

Венгерская нотация была разработана как независимая от языка и нашла свое первое широкое применение в языке программирования BCPL . Поскольку в BCPL нет других типов данных, кроме машинного слова , ничто в самом языке не помогает программисту запоминать типы переменных. Венгерская нотация призвана исправить это, предоставляя программисту явное знание типа данных каждой переменной.

В венгерской нотации имя переменной начинается с группы строчных букв, которые являются мнемоникой типа или назначения этой переменной, за которой следует любое имя, выбранное программистом; эта последняя часть иногда выделяется как имя . Первый символ имени может быть написан с заглавной буквы, чтобы отделить его от индикаторов типа (см. также CamelCase ). В противном случае регистр этого символа обозначает область действия.

История [ править ]

Оригинальную венгерскую нотацию придумал Чарльз Симони , программист, работавший в Xerox PARC примерно в 1972–1981 годах, а позже ставший главным архитектором в Microsoft . Название обозначения является отсылкой к стране происхождения Симони, а также, по словам Энди Херцфельда , потому, что оно делало программы «выглядящими так, как будто они написаны на каком-то непостижимом иностранном языке». [2] Имена венгерского народа «перевернуты» по сравнению с большинством других европейских имен; фамилия предшествует имени . Например, англизированное имя «Чарльз Симони» на венгерском языке изначально было «Симони Карой». Точно так же имя типа предшествует «имени» в венгерской записи. Похожий стиль именования Smalltalk «введите последний» (например, aPoint и LastPoint) был распространен в Xerox PARC во время пребывания там Симони. [ нужна ссылка ]

В статье Симони об обозначениях упоминаются префиксы, используемые для обозначения «типа» хранимой информации. [3] [4] Его предложение в основном касалось оформления имен идентификаторов на основе семантической информации о том, что они хранят (другими словами, назначения переменной ). Нотация Симони стала называться Венгерским приложением, поскольку это соглашение использовалось в отделе приложений Microsoft. Системы Венгерский были разработаны позже командой разработчиков Microsoft Windows . Венгерский язык приложений не полностью отличается от того, что стало известно как Венгерский язык систем, поскольку некоторые из предложенных Симони префиксов содержат мало или вообще не содержат семантической информации (примеры см. ниже). [4]

Венгерские системы венгерских против приложений

Нотации систем и нотаций приложений различаются назначением префиксов.

В системной венгерской нотации префикс кодирует фактический тип данных переменной. Например:

  • 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 , поэтому они иногда используются для хранения числовых значений. Этот префикс может устранить неоднозначность между тем, содержит ли переменная значение, которое следует рассматривать как символ или число.

Хотя в обозначениях в качестве мнемоники всегда используются начальные строчные буквы, они не предписывают саму мнемонику. Существует несколько широко используемых соглашений (см. примеры ниже), но можно использовать любой набор букв, если они согласованы в пределах данного фрагмента кода.

Код, использующий венгерскую нотацию приложений, может иногда содержать системный венгерский язык при описании переменных, которые определяются исключительно с точки зрения их типа.

Отношение к сигилам [ править ]

В некоторых языках программирования аналогичная нотация, которая теперь называется сигилами , встроена в язык и применяется компилятором. Например, в некоторых формах BASIC , name$ называет строку и count% называет целое число . Основное различие между венгерской нотацией и сигилами заключается в том, что сигилы объявляют тип переменной на языке, тогда как венгерская нотация представляет собой чисто схему именования, не влияющую на машинную интерпретацию текста программы.

Примеры [ править ]

За мнемоникой указателей и массивов , которые не являются фактическими типами данных, обычно следует тип самого элемента данных:

  • pszOwner : указатель на строку с нулевым завершением
  • rgfpBalances : массив с плавающей запятой значений
  • aulColors : массив длинных беззнаковых значений (системы)

Хотя венгерскую нотацию можно применять к любому языку программирования и среде, она была широко принята Microsoft для использования с языком C, в частности, для Microsoft Windows , и ее использование по-прежнему в основном ограничивается этой областью. В частности, использование венгерской нотации широко пропагандировалось в книге Чарльза Петцольда « Программирование Windows» , оригинальной (и для многих читателей окончательной) книге по программированию Windows API . Таким образом, многие часто встречающиеся конструкции венгерской нотации специфичны для Windows:

  • Для программистов, изучавших программирование Windows на языке C, вероятно, наиболее запоминающимися примерами являются 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]

  • Тип символа можно увидеть по его названию. Это полезно при просмотре кода вне интегрированной среды разработки — например, при проверке кода или распечатке — или когда объявление символа находится в другом файле с точки зрения использования, например в функции.
  • В языке, использующем динамическую типизацию или нетипизированном, украшения, ссылающиеся на типы, перестают быть избыточными. В таких языках переменные обычно не объявляются как содержащие определенный тип данных, поэтому единственным ключом к тому, какие операции с ними можно выполнять, являются подсказки, данные программистом, такие как схема именования переменных, документация и комментарии. Как упоминалось выше, на таком языке ( BCPL ) расширилась венгерская нотация.
  • Форматирование имен переменных может упростить некоторые аспекты рефакторинга кода (в то же время делая другие аспекты более подверженными ошибкам).
  • В блоке кода можно использовать несколько переменных со схожей семантикой: dwWidth, iWidth, fWidth, dWidth.
  • Имена переменных легко запомнить, зная только их типы.
  • Это приводит к более согласованным именам переменных.
  • Неподходящее приведение типов и операции с использованием несовместимых типов можно легко обнаружить при чтении кода.
  • В сложных программах со множеством глобальных объектов (формы VB/Delphi) наличие базовой префиксной нотации может облегчить работу по поиску компонента внутри редактора. Например, поиск строки btn может найти все объекты Button.
  • Более узкое применение венгерской нотации, например применение только к переменным-членам , помогает избежать конфликта имен .
  • Печатный код более понятен читателю в случае типов данных, преобразований типов, присваиваний, усечений и т. д.

Недостатки [ править ]

Большинство аргументов против венгерской нотации направлены против системной венгерской нотации, а не приложений венгерской нотации . Некоторые потенциальные проблемы:

  • Венгерская нотация является избыточной, когда проверка типов выполняется компилятором. Компиляторы языков, обеспечивающих строгую проверку типов, таких как Pascal , автоматически обеспечивают соответствие использования переменной ее типу; проверки на глаз излишни и подвержены человеческим ошибкам.
  • Большинство современных интегрированных сред разработки отображают типы переменных по требованию и автоматически помечают операции, использующие несовместимые типы, что делает эту нотацию в значительной степени устаревшей.
  • Венгерская нотация становится запутанной, когда она используется для представления нескольких свойств, как в a_crszkvc30LastNameCol: постоянной ссылки аргумент , содержащий содержимое базы данных . столбца LastName типа varchar таблицы (30), который является частью первичного ключа .
  • Это может привести к несогласованности при изменении или переносе кода. Если тип переменной изменен, либо оформление имени переменной будет несовместимо с новым типом, либо имя переменной необходимо изменить. Особенно хорошо известным примером является стандартный тип WPARAM и сопровождающий его формальный параметр wParam во многих объявлениях системных функций Windows. Буква «w» означает «слово», где «слово» — это собственный размер слова аппаратной архитектуры платформы. Первоначально это был 16-битный тип для 16-битных словных архитектур, но в более поздних версиях операционной системы он был изменен на 32-битный для 32-битных словных архитектур или на 64-битный тип для 64-битных словных архитектур в более поздних версиях операционной системы, сохранив при этом свой исходное имя (его истинный базовый тип — UINT_PTR, то есть целое число без знака, достаточно большое для хранения указателя). Семантический импеданс и, следовательно, путаница программистов и несогласованность от платформы к платформе основаны на предположении, что «w» обозначает двухбайтовое 16-битное слово в этих разных средах.
  • В большинстве случаев знание использования переменной подразумевает знание ее типа. Более того, если использование переменной неизвестно, ее невозможно вывести из ее типа.
  • Венгерская нотация снижает преимущества использования редакторов кода, поддерживающих завершение имен переменных, поскольку программисту приходится сначала вводить спецификатор типа, что с большей вероятностью будет конфликтовать с другими переменными, чем при использовании других схем именования.
  • Это делает код менее читабельным, запутывая назначение переменной префиксами типа и области видимости. [8]
  • Дополнительная информация о типе не может заменить более описательные имена. Например, sDatabase не сообщает читателю, что это такое. имя_базы_данных могло бы быть более описательным именем.
  • Когда имена достаточно описательны, дополнительная информация о типе может быть избыточной. Например, firstName, скорее всего, является строкой. Поэтому присвоение ему имени sFirstName только добавляет беспорядка в код.
  • Сложнее запомнить имена.
  • несколько переменных с разной В блоке кода со схожими именами можно использовать семантикой: dwTmp, iTmp, fTmp, dTmp .
  • Размещение идентификаторов типа данных или символа намерения в качестве префикса к заданному имени поля или переменной лишает возможности в некоторых средах программирования переходить к имени поля или переменной в алфавитном порядке, когда пользователь начинает вводить имя. Файлмейкер, [9] например, является одной из таких сред программирования. При использовании одной из этих сред программирования может быть предпочтительнее добавлять к имени имени такие идентифицирующие символы.

Известные мнения [ править ]

  • Роберт Сесил Мартин (против венгерской нотации и всех других форм кодирования):

    ... в настоящее время HN и другие формы кодирования типов являются просто препятствиями. Они затрудняют изменение имени или типа переменной, функции, члена или класса. Они затрудняют чтение кода. И они создают возможность того, что система кодирования введет читателя в заблуждение. [10]

  • Линус Торвальдс (против «Систем Венгерский»):

    Закодировать тип функции в имя (так называемая венгерская нотация) — это повреждение мозга — компилятор все равно знает типы и может их проверить, а это только запутывает программиста. [11]

  • Стив МакКоннелл (от Apps на венгерском языке):

    Хотя венгерское соглашение об именах больше не широко используется, основная идея стандартизации кратких и точных сокращений продолжает иметь ценность. Стандартизированные префиксы позволяют точно проверять типы, когда вы используете абстрактные типы данных, которые ваш компилятор не может проверить. [12]

  • Бьярне Страуструп (против систем венгерского языка за C++):

    Нет, я не рекомендую «венгерский». Я рассматриваю «венгерский» (встраивание сокращенной версии типа в имя переменной) как метод, который может быть полезен в нетипизированных языках, но совершенно непригоден для языков, поддерживающих обобщенное программирование и объектно-ориентированное программирование — оба из которых подчеркивают выбор операций по типу и аргументам (известным языку или поддержке времени выполнения). В этом случае «встраивание типа объекта в имена» просто усложняет и сводит к минимуму абстракцию. [13]

  • Джоэл Спольски (для приложений на венгерском языке):

    Если вы внимательно прочитаете статью Симони, то увидите, что он имел в виду такое же соглашение об именах, которое я использовал в своем примере выше, где мы решили, что us означало небезопасную строку и s имелась в виду безопасная строка. Они оба типа string. Компилятор не поможет вам, если вы присвоите одно другому, а Intellisense [ интеллектуальная система завершения кода ] не сообщит вам bupkis . Но они семантически различны. Их нужно интерпретировать по-разному и обрабатывать по-разному, и если вы назначите одно другому, потребуется вызвать какую-то функцию преобразования, иначе у вас возникнет ошибка во время выполнения. Если вам повезет. Apps Венгерский по-прежнему имеет огромную ценность, поскольку он увеличивает коллокацию кода, что упрощает чтение, запись, отладку и поддержку кода и, что наиболее важно, делает неправильный код неправильным.... (Системы венгерский) было тонким, но полным непониманием намерений и практики Симони. [4]

  • проектированию Рекомендации Microsoft по [14] не рекомендуется разработчикам использовать системную венгерскую нотацию при выборе имен для элементов в библиотеках классов .NET, хотя это было обычным явлением на предыдущих платформах разработки Microsoft, таких как Visual Basic 6 и более ранние версии. В этих рекомендациях по проектированию ничего не говорится о соглашениях об именах локальных переменных внутри функций.

См. также [ править ]

Ссылки [ править ]

  1. ^ «Устная история Чарльза Симони» (PDF) . Archive.computerhistory.org\accessdate=5 августа 2018 г. Архивировано (PDF) из оригинала 10 сентября 2015 г.
  2. ^ Розенберг, Скотт (1 января 2007 г.). «Все, что вы можете сделать, я могу сделать мета» . Обзор технологий Массачусетского технологического института . Проверено 21 июля 2022 г.
  3. Перейти обратно: Перейти обратно: а б с Чарльз Симони (ноябрь 1999 г.). «Венгерская нотация» . Библиотека MSDN . Корпорация Майкрософт
  4. Перейти обратно: Перейти обратно: а б с Спольски, Джоэл (11 мая 2005 г.). «Как сделать неправильный код неправильным» . Джоэл о программном обеспечении . Проверено 13 декабря 2005 г.
  5. ^ «Стиль кодирования Mozilla» . Developer.mozilla.org . Архивировано из оригинала 2 декабря 2019 года . Проверено 17 марта 2015 г.
  6. ^ «Руководство по стилю кодирования Webkit» . Вебкит.орг . Проверено 17 марта 2015 г.
  7. ^ «Почему переменная JavaScript начинается со знака доллара?» . Переполнение стека . Проверено 12 февраля 2016 г.
  8. ^ Джонс, Дерек М. (2009). Новый стандарт C: культурный и экономический комментарий (PDF) . Аддисон-Уэсли. п. 727. ИСБН  978-0-201-70917-9 . Архивировано (PDF) из оригинала 1 мая 2011 г.
  9. ^ «Создайте приложение для любой задачи — FileMaker — дочерняя компания Apple» . Filemaker.com . Проверено 5 августа 2018 г.
  10. ^ Мартин, Роберт Сесил (2008). Чистый код: Руководство по гибкому созданию программного обеспечения . Редмонд, Вашингтон: PTR Прентис Холл. ISBN  978-0-13-235088-4 .
  11. ^ «Стиль кодирования ядра Linux» . по ядру Linux Документация . Проверено 9 марта 2018 г.
  12. ^ МакКоннелл, Стив (2004). Код завершен (2-е изд.). Редмонд, Вашингтон: Microsoft Press . ISBN  0-7356-1967-0 .
  13. ^ Страуструп, Бьярн (2007). «Часто задаваемые вопросы по стилю и технике C++ Бьярна Страуструпа» . Проверено 15 февраля 2015 г.
  14. ^ «Рекомендации по проектированию библиотек классов: общие соглашения об именах» . Проверено 3 января 2008 г.

Внешние ссылки [ править ]