本頁使用了標題或全文手工轉換

匈牙利命名法

維基百科,自由的百科全書
跳至導覽 跳至搜尋

匈牙利命名法是電腦程式設計中的一種變數命名規則,此命名法又可細分為:系統匈牙利命名法匈牙利應用命名法

匈牙利命名法具備語言獨立的特性,並且首次在BCPL語言中被大量使用。由於BCPL只有機器字這一種數據型別,因此這種語言本身無法幫助程式設計師來記住變數的類型。匈牙利命名法通過明確每個變數的數據型別來解決這個問題。

在匈牙利命名法中,一個變數名由一個或多個小寫字母開始,這些字母有助於記憶變數的類型和用途,緊跟着的就是程式設計師選擇的任何名稱。這個後半部分的首字母可以大寫,以區別前面的類型指示字母(參見駝峰式大小寫)。

歷史[編輯]

原始的匈牙利命名法,現在被稱為匈牙利應用命名法,由1972年至1981年在施樂帕洛阿爾托研究中心工作的-程式設計師查爾斯·西蒙尼發明。此人後來成了微軟的總設計師。

這種命名法其實是對於西蒙尼祖籍的一種諷刺。匈牙利人名和大多數其他歐洲人名相比是反過來的,即姓氏在名字的前面。舉個例子,英語化的名字「Charles Simonyi」在匈牙利語中原本是「Simonyi Károly」。同樣的,在匈牙利命名法中,類型名在實際變數名前,而不是像大多數歐洲的Smalltalk那樣,類型放在變數名後,例如aPoint和lastPoint。後者在西蒙尼任職於施樂帕洛阿爾托研究中心時期非常流行。這種命名法的靈感,可能是受波蘭表示法的啟發。

匈牙利命名法的英文是Hungarian notation,這個詞能讓許多人記住,因為難發音的輔音字串有點像部份東歐語言中,輔音豐富的拼寫方式,儘管實際上匈牙利語是屬於芬蘭-烏戈爾語族,而不像斯拉夫語族那樣元音豐富。舉例來說,零結束字串的字首"sz"實際上就是匈牙利字母表中的一個合體字母(參看德語中的ß)。

系統匈牙利命名法與匈牙利應用命名法[編輯]

系統命名法與應用命名法的區別在於字首的目的。

在系統匈牙利命名法中,字首代表了變數的實際數據類型。例如:

  • lAccountNum:變數是一個長整數("l");
  • arru8NumberList:變數是一個無符號8位元整型陣列("arru8");
  • szName:變數是一個零結束字串("sz"),這是西蒙尼最開始建議的字首之一。

匈牙利應用命名法不表示實際數據類型,而是給出了變數目的的提示,或者說它代表了什麼。

  • rwPosition:變數代表一個("rw")。
  • usName:變數代表一個非安全字串("us"),需要在使用前處理。
  • strName:變數代表一個包含名字的字串("str")但是沒有指明這個字串是如何實現的。

西蒙尼建議的大多數字首都是自然語意的,但不是所有。下面幾個是來自原始論文的: [1]

  • pX是指向另一個X類型的指標,這包含非常少的語意資訊。
  • d是一個字首表示兩個值的區別,例如,dY可能代表一個圖形沿Y軸的距離,而一個僅僅叫做y的變數可能是一個絕對坐標。這完全是自然語意的。
  • sz是一個無結束或零結束的字串。在C中,這包含一些語意資訊,因為它不是很明確一個char*類型的變數是一個指向單個字元的指標,還是一個字元陣列,或是一個零結束字串。
  • w標記一個變數是一個字。這基本上沒有包含什麼語意資訊,因此大概會被當成是系統命名法。
  • b標記了一個位元組,和w對比可能有一些語意資訊,因為C語言中,只有位元組大小的數據是char型的,因此這些有時候被用來儲存數值。這個字首也許可以明確某個變數儲存的是應該被看作是字母(或更一般的字元)的數值還是一個數字。

由於這種命名法通常使用小寫字母開頭用來助記,但是並沒有對助憶碼本身作規定。有幾種被廣泛使用的習慣(見下面的範例),但是任意字母組合都可以被使用,只要它們在代碼主體中保持一致就可以了。

在使用匈牙利系統命名法的代碼中有時候也可能包含系統匈牙利命名法,即在描述被單獨以類型方式定義的變數時使用。

範例[編輯]

  • bBusy布林型
  • cApples:專案計數
  • dwLightYears:雙(系統)
  • fBusy布林型(標記)
  • nSize整型(系統)或計數(應用程式)
  • iSize整型(系統)或索引(應用程式)
  • fpPrice浮點數
  • dbPi雙精度浮點數(系統)
  • pFoo指標
  • rgStudents:陣列或範圍
  • szLastName:零結束字串
  • u32Identifier:無符號32位元整型(系統)
  • stTime:時鐘結構
  • fnFunction:函數名

對於指標和陣列來說,它們實際上並不是數據類型,因此通常在助憶碼後面跟着實際元素的類型。

  • pszOwner:指向零結束字串的指標
  • rgfpBalances浮點值的陣列

由於匈牙利命名法可以被應用在任何程式語言和環境中,因此被微軟廣泛用在C語言中,特別是在Microsoft Windows裏。由此一來,許多常見的匈牙利命名法的結構都和Windows緊密相關:

  • hwndFoo:窗口控制代碼
  • lpszBar:指向零結束字串的長指標

這種命名法又是在C++中被擴充功能而包含變數的作用域,由一個底線隔開:

  • g_nWheels:全局命名空間的成員,整型
  • m_nWheels:結構體/類別成員,整型

系統匈牙利命名法的優點[編輯]

(其中一些只適用於系統匈牙利命名法) 支持者聲稱匈牙利命名法的好處包括:[2]

  • 從名字中就可以看出變數的類型
  • 擁有類似語意的多個變數可以在一個代碼塊中使用:dwWidth,iWidth,fWidth,dWidth
  • 變數名在僅僅知道他們的類型時可以被輕易記住
  • 可以使變數名更加一致
  • 決定一個變數名的時候可以更機械化,更快
  • 不合適的類型轉換和操作可以在閱讀代碼的時候被檢測出來
  • 在那些數字被當作字串處理的基於字串的語言中非常有用(例如Tcl
  • 在匈牙利應用命名法中,變數名確保不會犯以下錯誤:
heightWindow = window.getWidth()
  • 在使用動態型別語言或完全無類型的語言編程時,關於類型的修飾可以更簡化。這種語言一般不包含類型修飾(或者可選),因此唯一可以看出哪些類型是被允許的只有名字本身、文件以及通過閱讀代碼來明白它們在做什麼。在這些語言中,包含對於變數類型的指示可能會有助於程式設計師。就像上面提到的,匈牙利命名法擴充功能了這樣的語言(BCPL)。
  • 在包含許多全局物件的複雜程式中(VB/Delphi Forms),擁有一個基本的字首命名法可以簡化在編輯器中尋找元件的工作。按btn<Ctrl-Space>可以使編輯器彈出一個Button物件的列表。

匈牙利系統命名法的缺點[編輯]

批評者認為:

  • 匈牙利命名法在編譯器做型別檢查時是多餘的。一個提供型別檢查的語言在確定一個變數與其類型一致時,比人眼僅僅檢查變數的用法與變數名一致要強大的多。
  • 一些現代的整合式開發環境,如Visual Studio在需要時可以顯示變數類型,並且自動標記不符合的類型。使用這種命名法完全沒有必要。
  • 匈牙利命名法在被用作代表多個屬性的時候會造成困惑,如 a_crszkvc30LastNameCol:一個常數參照參數,儲存了一個varchar(30)類型的數據庫LastName的內容,而這列又是這個表的主鍵的一部分。
  • 在代碼更改後可能造成不一致。如果一個變數的類型改變了,不是變數名的修飾與新的類型不一致,就是變數名必須被改變。
  • 由於變數名和類型捆綁在一起,因此不利於代碼的移植。一個典型的眾所周之的例子就是WPARAM類型,以及在許多Windows系統函數聲明中使用的wParam參數。它原本是一個16位元的類型,但是在後來的作業系統中被改成了32位元或64位元,但仍保留原來的名字(它實際的基礎類型是UINT_PTR,即一個大小足夠儲存一個指標的無符號整型)。
  • 大多數時候,看到一個變數就意味着知道了它的類型。但是,如果你不知道一個變數是幹什麼的,知道了它的類型也沒什麼幫助。

.NET Framework,微軟新的軟件開發平台,除了介面類型一般不適用匈牙利命名法。在.NET中,習慣在介面類型前放一個I(例如Windows Forms中的IButtonControl介面。).NET Framework指導方針建議程式設計師不要用匈牙利命名法,但是沒有指明不要用系統匈牙利命名法還是匈牙利應用命名法,或者是兩者都不要用。[3]與此對比,Java的標準庫中連介面類型也不加字首。[4]

注釋和參考[編輯]

內部連結[編輯]

外部連結[編輯]