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

Венге́рская нота́ция в программировании — соглашение об именовании переменных, констант и прочих идентификаторов в коде программ. Своё название венгерская нотация получила благодаря программисту компании Microsoft венгерского происхождения Чарльзу Симони, Шимоньи Карой), предложившему её ещё во времена разработки первых версий MS-DOS. Эта система стала внутренним стандартом «Майкрософт»[1].

История

править

Изобретение нотации приписывают программисту венгерского происхождения Чарльзу Шимоньи (венг. Simonyi Károly, Ши́моньи Ка́рой), который в 1972—1981 годах работал в Xerox PARC года, а позднее — в Microsoft, где руководил, в частности, разработкой Microsoft Word. Венгерской нотацию стали называть из-за страны происхождения Шимоньи, а также потому, что код «выглядел, как будто он написан на нечитаемом иностранном языке», со слов Энди Хетцфельда.[2] Венгерский язык и в самом деле непривычен для англоговорящих, потому что относится к финно-угорским языкам, далёким от привычных индоевропейских.

Правила

править

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

Применяемая система префиксов зависит от многих факторов:

  • языка программирования (чем более «либеральный» синтаксис, тем больше контроля требуется со стороны программиста, а значит, тем более развита система префиксов. К тому же использование в каждом из языков программирования своей терминологии также вносит особенности в выбор префиксов);
  • стиля программирования (объектно-ориентированный код может вообще не требовать префиксов, в то время как в «монолитном» для разборчивости они зачастую нужны);
  • предметной области (например, префиксы могут применяться для записи единиц измерения);
  • доступных средств автоматизации (генератор документации, навигация по коду, предиктивный ввод текста, автоматизированный рефакторинг и т. д.).

Префиксы, задающие тип

править
Префикс Сокращение от Смысл Пример
s string строка sClientName
sz zero-terminated string строка, ограниченная нулевым символом szClientName
n, i int целочисленная переменная nSize, iSize
f float число с плавающей запятой fValue
l long длинное целое lAmount
b boolean булева переменная bIsEmpty
a array массив aDimensions
t, dt time, datetime время, дата и время tDelivery, dtDelivery
p pointer указатель pBox
lp long pointer двойной (дальний) указатель lpBox
r reference ссылка rBoxes
h handle дескриптор hWindow
m_ member переменная-член m_sAddress
g_ global глобальная переменная g_nSpeed
C class класс CString
T type тип TObject
I interface интерфейс IDispatch
v void отсутствие типа vReserved

Как видно в приведённом примере, префикс может быть и составным. Например, для именования строковой переменной-члена класса использована комбинация префиксов «m_» и «s» (m_sAddress).

Семантические префиксы

править

Венгерская нотация для приложений[источник не указан 3037 дней]:

Префикс Сокращение от Смысл Пример
i index Индекс int ix; Array[ix] = 10;
d delta Разница между значениями int a, b; ... dba = b - a;
n number Количество size_t nFound = 0;
a argument Аргумент SomeClass::SomeClass(int aX) : x(aX) {}
I interface Интерфейс (в имени типа) interface IFactory {}

За и против

править

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

Преимущества

править
  • Если встроенного механизма типизации не хватает, венгерская нотация позволяет записывать подтип[англ.] переменной — например, int cPrice может означать, что переменная имеет не просто целый тип, а валютный (currency). Именно такое применение префиксов было предложено Симони[3]. Это может пригодиться:
    • В низкоуровневом программировании (когда набор доступных типов настолько узок, что, например, целый тип не отличается от булевого).
    • В языках с динамической типизацией, например PHP, где одна и та же переменная может хранить значения любого типа.
    • В инженерных расчётах (для записи единиц измерения). Это позволяет избавиться от немалого количества ошибок простым подсчётом размерностей.
    • В других местах, где переменные одного и того же типа предназначены для хранения разнородных данных — например, в коде защиты от компьютерных взломщиков префикс может указывать на «необработанные» и «экранированные» данные (SQL-инъекция, XSS).
  • Венгерская нотация удобна для написания больших программ в неполнофункциональных (по современным меркам) редакторах без автоматизированной навигации по тексту. Скорее всего, именно поэтому она стала стандартным стилем кода в WinAPI.
  • Венгерскую нотацию можно рассматривать как стандартную систему сокращений. Например, поле ввода для поиска и кнопка «Поиск» могут именоваться как txtSearch и btnSearch; количество людей можно записать как manCount или nMen. Такая практика позволяет делать названия переменных короткими и в то же время осмысленными.
  • Решает конфликты идентификаторов: Point::Point(int aX, int aY) : x(aX), y(aY) {}.

Недостатки

править
  • Некоторые программисты считают, что использование префиксов делает имена переменных менее понятными и, таким образом, ухудшает читаемость кода.[5]
  • Если неизвестно имя переменной без префиксов, подчас трудно восстановить её префиксы.
  • Система автодокументации, если она не понимает системы префиксов, отсортирует алфавитный список по префиксу, что может отрицательно сказаться на качестве документации. Впрочем, имена функций обычно префиксами не снабжают.
  • Запись нескольких префиксов из-за частого использования заглавных букв и знаков подчёркивания может стать «пляской на кнопке ⇧ Shift».
  • Средства навигации, которые включены в современные редакторы кода, и так позволяют видеть тип любой переменной и быстро переходить к точке, где она определена — то есть, использование префиксов может быть избыточным.
  • При изменении типа потребуется изменять имя переменной (не все редакторы кода могут делать это автоматически).[5]
  • Существуют и другие средства задания типа переменной в её имени: например, слова is, has и т. д. для булевского типа (IsLoggedIn), count для счётчика (RefCount), множественное число для массива (UserIds). В языках, в которых заглавные буквы не эквивалентны строчным, регистр букв также может кодировать что-либо.

Известный противник венгерской нотации — Линус Торвальдс: «Вписывание типа переменной в её имя (так называемая венгерская нотация) ущербно — компилятор и так знает типы и может проверить их, и это запутывает программиста»[6].

См. также

править

Примечания

править
  1. Charles Simonyi. Hungarian Notation.
  2. Anything You Can Do, I Can Do Meta MIT Technology Review
  3. Джоэл Спольски. Making Wrong Code Look Wrong
  4. Венгерский язык, хоть и имеет латинский алфавит, считается крайне неудобочитаемым для неосведомлённых.
  5. 1 2 Необходимо задать параметр url= в шаблоне {{cite web}}. [ Inside C++ — Венгерская нотация]. Дата обращения: 12 ноября 2008. Архивировано 30 октября 2008 года.
  6. «Linux kernel coding style» Архивировано 23 сентября 2005 года.. Документация по ядру Linux (на английском).