幾年以前,Charles Simonyi(他后來成為微軟的著名程序員)設計了一種以前綴為基礎的命名方法,這種方法后來稱為"匈牙利表示法"以記念他.他的思想是根據每個標識符所代表的含義給它一個前綴.微軟后來采用了這個思想,給每個標識符一個前綴以說明它的數據類型.因此,整型變量的前綴是n,長整型變量是nl,字符型數組變量是ca,以及字符串(以空類型結尾的字符數組)以sz為前綴.這些名字可能會非常古怪.比如說:lpszFoo表示"Foo"是一個指向以空字符為結尾的字符串的長整型指針.
這種方法的優點是使人能夠通過變量的名字來辨別變量的類型,而不比去查找它的定義.遺憾的是,這種方法不僅使變量名字非常繞口,而且使改變變量類型的工作變得十分艱巨.在Windows3.1中,整型變量為16為寬.如果我們在開始時采用了一個整型變量,但是在通過30---40個函數的計算之后,發現采用整型變量寬度不夠,這時我們不僅要改變這個變量的類型,而且要改變這個變量在這30--40個函數中的名字.
因為不切實際,除了一些頑固的Windows程序員外已經沒有人再使用"匈牙利表示法"了.毫無疑問,在某種場合它依然存在,但大部分人現在已經拋棄它了.一般而言,輸入前綴是一種糟糕的想法,因為它把變量於其類型緊緊地綁在了一起.
對於30行以下的函數,匈牙利方法一般有優勢。
尤其是對界面編程,有優勢。
但對於有強烈的算法要求、尤其是有很多抽象類型的C++程序,匈牙利方法簡直是一個災難。
看你用在什么地方。
現在有了很好的IDE工具,如:VC,SourceInsight等.
選中變量,會自動提示告訴你它的聲明和定義,這樣
匈牙利命名法就沒有很大的必要了.
無非就是為了程序可讀性較好.
實際上良好的代碼書寫習慣比強制使用匈牙利命名法更重要.
系統性。整體性。可讀性。分類要清楚。要有注釋!
匈牙利命名法是微軟推廣的一種關於變量、函數、對象、前綴、宏定義等各種類型的符號的命名規范。匈牙利命名法的主要思想是:在變量和函數名中加入前綴以增進人們對程序的理解。它是由微軟內部的一個匈牙利人發起使用的,結果它在微軟內部逐漸流行起來,並且推廣給了全世界的Windows開發人員。下面將介紹匈牙利命名法,后面的例子里也會盡量遵守它和上面的代碼風格。還是那句話,並不是要求所有的讀者都要去遵守,但是希望讀者作為一個現代的軟件開發人員都去遵守它。
| 前綴 | 類型 | 中文說明 |
| a | Array | 數組 |
| b | BOOL(int) | 布爾(整數) |
| by | Unsigned Char(Byte) | 無符號字符(字節) |
| c | Char | 字符(字節) |
| cb | Count of Bytes | 字節數 |
| cr | Color Reference Value | 顏色(參考)值 |
| cx | Count of x(Short) | x的集合(短整數) |
| f | Flags(usually multiple bit values) | 標志(一般是有多位的數值) |
| fn | Function | 函數 |
| g_ | Global | 全局的 |
| h | Handle | 句柄 |
| i | Integer | 整數 |
| l | Long | 長整數 |
| lp | Long Pointer | 長指針 |
| m_ | Data Member of a Class | 一個類的數據成員 |
| n | Short Integer | 短整數 |
| p | Pointer | 指針 |
| s | String | 字符串 |
| sz | Zero Terminated String | 以零結尾的字符串 |
| tm | Text Metric | 文本規則 |
| u | Unsigned Integer | 無符號整數 |
| ul | Unsigned Long(ULONG) | 無符號長整數 |
| w | WORD(Unsigned Short) | 無符號短整數 |
| x,y | x, y Coordinates (Short) | 坐標值(短整數) |
| v | Void | 空 |
有關項目的全局變量用g_開始,類成員變量用m_,局部變量若函數較大則可考慮用l_用以顯示說明其是局部變量。
| 前綴 | 類型 | 例子 |
| g_ | 全局變量 | g_Servers |
| C | 類或者結構體 | CDocument, CPrintInfo |
| m_ | 成員變量 | m_pDoc, m_nCustomers |
VC常用前綴列表:
| 前綴 | 類型 | 描述 | 例子 |
| ch | char | 8位字符 | chGrade |
| ch | TCHAR | 16位Unicode集字符 | chName |
| b | BOOL | 布爾變量 | bEnable |
| n | int | 整型 | nLength |
| n | UINT | 無符整型 | nLength |
| w | WORD | 16位無符號整型 | wPos |
| l | Long | 32位有符號整型 | lOffset |
| dw | DWORD | 32位無符號整型 | dwRange |
| p | * | 指針變量,內存模塊指針(Ambient memory model point) | pDoc |
| lp | Far* | 長指針 | lpDoc |
| lpsz | LPSTR | 32位字符串指針 | lpszName |
| lpsz | LPCSTR | 32位常量字符串指針 | lpszName |
| lpsz | LPCTSTR | 32位Unicode集常量指針 | lpszName |
| h | handle | Windows對象句柄 | hWnd |
| lpfn | (*fn)() | 回調函數指針 Callback Far pointer to CALLBACK function | lpfnAbort |
MFC、句柄、控件及結構的命名規范:
| Windows類型 | 樣本變量 | MFC類 | 樣本變量 |
| HWND | hWnd | CWnd* | pWnd |
| HDLG | hDlg | CDialog* | pDlg |
| HDC | hDC | CDC* | pDC |
| HGDIOBJ | hGdiObj | CGdiObject* | pGdiObj |
| HPEN | hPen | CPen* | pPen |
| HBRUSH | hBrush | CBrush* | pBrush |
| HFONT | hFont | CFont* | pFont |
| HBITMAP | hBitmap | CBitmap* | pBitmap |
| HPALETTE | hPaltte | CPalette* | pPalette |
| HRGN | hRgn | CRgn* | pRgn |
| HMENU | hMenu | CMenu* | pMenu |
| HWND | hCtl | CState* | pState |
| HWND | hCtl | CButton* | pButton |
| HWND | hCtl | CEdit* | pEdit |
| HWND | hCtl | CListBox* | pListBox |
| HWND | hCtl | CComboBox* | pComboBox |
| HWND | hCtl | CScrollBar* | pScrollBar |
| HSZ | hszStr | CString | pStr |
| POINT | pt | CPoint | pt |
| SIZE | size | CSize | size |
| RECT | rect | CRect | rect |
一般前綴命名規范:
| 前綴 | 類型 | 實例 |
| C | 類或結構 | Cdocument, CPrintInfo |
| m_ | 成員變量 | m_pDoc, m_nCustomers |
變量命名規范:
| 前綴 | 類型 | 描述 | 實例 |
| ch | char | 8位字符 | chGrade |
| ch | TCHAR | 如果_UNICODE定義,則為16位字符 | chName |
| b | BOOL | 布爾值 | bEnable |
| n | int | 整型(其大小依賴於操作系統) | nLength |
| n | UINT | 無符號值(其大小依賴於操作系統) | nHeight |
| w | WORD | 16位無符號值 | wPos |
| l | LONG | 32位有符號整型 | lOffset |
| dw | DWORD | 32位無符號整型 | dwRange |
| p | * | 指針 | pDoc |
| lp | FAR* | 遠指針 | lpszName |
| lpsz | LPSTR | 32位字符串指針 | lpszName |
| lpsz | LPCSTR | 32位常量字符串指針 | lpszName |
| lpsz | LPCTSTR | 如果_UNICODE定義,則為32位常量字符串指針 | lpszName |
| h | handle | Windows對象句柄 | hWnd |
| lpfn | callback | 指向CALLBACK函數的遠指針 |
| 前綴 | 符號類型 | 實例 | 范圍 |
| IDR_ | 不同類型的多個資源共享標識 | IDR_MAIINFRAME | 1~0x6FFF |
| IDD_ | 對話框資源 | IDD_SPELL_CHECK | 1~0x6FFF |
| HIDD_ | 對話框資源的Help上下文 | HIDD_SPELL_CHECK | 0x20001~0x26FF |
| IDB_ | 位圖資源 | IDB_COMPANY_LOGO | 1~0x6FFF |
| IDC_ | 光標資源 | IDC_PENCIL | 1~0x6FFF |
| IDI_ | 圖標資源 | IDI_NOTEPAD | 1~0x6FFF |
| ID_ | 來自菜單項或工具欄的命令 | ID_TOOLS_SPELLING | 0x8000~0xDFFF |
| HID_ | 命令Help上下文 | HID_TOOLS_SPELLING | 0x18000~0x1DFFF |
| IDP_ | 消息框提示 | IDP_INVALID_PARTNO | 8~0xDEEF |
| HIDP_ | 消息框Help上下文 | HIDP_INVALID_PARTNO | 0x30008~0x3DEFF |
| IDS_ | 串資源 | IDS_COPYRIGHT | 1~0x7EEF |
| IDC_ | 對話框內的控件 | IDC_RECALC | 8~0xDEEF |
應用程序符號命名規范
Microsoft MFC宏命名規范:
| 名稱 | 類型 |
| _AFXDLL | 唯一的動態連接庫(Dynamic Link Library,DLL)版本 |
| _ALPHA | 僅編譯DEC Alpha處理器 |
| _DEBUG | 包括診斷的調試版本 |
| _MBCS | 編譯多字節字符集 |
| _UNICODE | 在一個應用程序中打開Unicode |
| AFXAPI | MFC提供的函數 |
| CALLBACK | 通過指針回調的函數 |
庫標識符命名法:
| 標識符 | 值和含義 |
| u | ANSI(N)或Unicode(U) |
| d | 調試或發行:D = 調試,忽略標識符為發行。 |
靜態庫版本命名規范:
| 庫 | 描述 |
| NAFXCWD.LIB | 調試版本:MFC靜態連接庫 |
| NAFXCW.LIB | 發行版本:MFC靜態連接庫 |
| UAFXCWD.LIB | 調試版本:具有Unicode支持的MFC靜態連接庫 |
| UAFXCW.LIB | 發行版本:具有Unicode支持的MFC靜態連接庫 |
動態連接庫命名規范:
| 名稱 | 類型 |
| _AFXDLL | 唯一的動態連接庫(DLL)版本 |
| WINAPI | Windows所提供的函數 |
Windows.h中新的命名規范:
| 類型 | 定義描述 |
| WINAPI | 使用在API聲明中的FAR PASCAL位置,如果正在編寫一個具有導出API人口點的DLL,則可以在自己的API中使用該類型 |
| CALLBACK | 使用在應用程序回叫例程,如窗口和對話框過程中的FAR PASCAL的位置 |
| LPCSTR | 與LPSTR相同,只是LPCSTR用於只讀串指針,其定義類似(const char FAR*) |
| UINT | 可移植的無符號整型類型,其大小由主機環境決定(對於Windows NT和Windows 9x為32位);它是unsigned int的同義詞 |
| LRESULT | 窗口程序返回值的類型 |
| LPARAM | 聲明lParam所使用的類型,lParam是窗口程序的第四個參數 |
| WPARAM | 聲明wParam所使用的類型,wParam是窗口程序的第三個參數 |
| LPVOID | 一般指針類型,與(void *)相同,可以用來代替LPSTR |
MSDN中給出了一段遵守代碼風格和匈牙利命名法的代碼參考如下:
1 #include "sy.h" 2 extern int *rgwDic; 3 extern int bsyMac; 4 struct SY *PsySz(char sz[]) 5 { 6 char *pch; 7 int cch; 8 struct SY *psy, *PsyCreate(); 9 int *pbsy; 10 int cwSz; 11 unsigned wHash=0; 12 pch=sz; 13 while (*pch!=0) 14 wHash=wHash<>11+*pch++; 15 cch=pch-sz; 16 pbsy=&rgbsyHash[(wHash&077777)%cwHash]; 17 for (; *pbsy!=0; pbsy = &psy->bsyNext) 18 { 19 char *szSy; 20 szSy= (psy=(struct SY*)&rgwDic[*pbsy])->sz; 21 pch=sz; 22 while (*pch==*szSy++) 23 { 24 if (*pch++==0) 25 return (psy); 26 } 27 } 28 cwSz=0; 29 if (cch>=2) 30 cwSz=cch-2/sizeof(int)+1; 31 *pbsy=(int *)(psy=PsyCreate(cwSY+cwSz))-rgwDic; 32 Zero((int *)psy,cwSY); 33 bltbyte(sz, psy->sz, cch+1); 34 return(psy); 35 }
