[목차] == 개요 == [[프로그래밍 언어]]에서 변수 및 함수의 인자 이름 앞에 데이터 타입을 명시하는 코딩 규칙이다. 찰스 시모니(Charles Simonyi) 가 [[마이크로소프트]]의 개발 책임자로 있을 때 제안했으며, 80년대 당시에는 [[통합 개발 환경|IDE]]라는게 다들 부실했기 때문에 ~~물론 볼랜드의 [[C(프로그래밍 언어)#s-6|Turbo C]] 같은 예외도 있었지만~~ 이 규칙이 엄청난 센세이션을 불러 일으켰다. 하지만 지금은 MS도 공식 가이드라인에서 사용하지 말 것을 권고[* [[https://msdn.microsoft.com/en-us/library/ms229045(v=vs.100).aspx]] 내용 자체는 [[.NET#Framework|.NET Framework]]에 적용되는 문서이긴 하지만 새로 만드는 SDK의 API들은 헝가리안 표기법에서 탈피하고 있다.]하고 있다. 헝가리안 표기법이라는 명칭은 '''제안자인 찰스 시모니가 [[헝가리]]인이라서''' 붙은 것이다. == 적용하기 == 아래 표만 잘 기억하면 된다. [[참 쉽죠?]] 물론 이렇게 정해야 한다는 명확한 룰 자체가 없으므로, 사용자나 이를 설명한 사이트에 따라 조금씩 다를 수는 있다. === Systems Notation === 데이터의 타입을 명시하는 방식으로, 널리 알려진 방식이다. 이런 방식 자체는 6,70년대 C언어 이전 타입시스템이 없는 언어에서 변수명에 변수의 타입을 명시해서 사용한 것이 시초이다. ==== 공통 ==== || 접두어 || 데이터 타입 || || {{{b}}} || {{{byte}}}, {{{boolean}}} || || {{{n}}} || {{{int}}}, {{{short}}} || || {{{i}}} || {{{int}}}, {{{short}}} (주로 인덱스로 사용) || || {{{c}}} || {{{int}}}, {{{short}}} (주로 크기로 사용) || || {{{l}}} || {{{long}}} || || {{{f}}} || {{{float}}} || || {{{d}}}, {{{db}}} || {{{double}}} || || {{{ld}}} || {{{long double}}} || || {{{w}}} || {{{word}}} || || {{{dw}}} || {{{double word}}} || || {{{qw}}} || {{{quad word}}} || || {{{ch}}} || {{{char}}} || || {{{sz}}} || {{{NULL}}}로 끝나는 문자열 || || {{{str}}} || C++ 문자열 || || {{{arr}}} || 배열 (문자열 제외): 다른 접두어와 조합 가능 || || {{{p}}} || 포인터 (16비트, 32비트): 다른 접두어와 조합 가능 || || {{{lp}}} || 포인터 (64비트): 다른 접두어와 조합 가능 || || {{{psz}}} || {{{NULL}}}로 끝나는 문자열을 가리키는 포인터 (16비트, 32비트) || || {{{lpsz}}} || {{{NULL}}}로 끝나는 문자열을 가리키는 포인터 (64비트) || || {{{fn}}} || 함수 타입 || || {{{pfn}}} || 함수 포인터 (16비트, 32비트) || || {{{lpfn}}} || 함수 포인터 (64비트) || ==== OOP ==== || 접두어 || 데이터 타입 || || {{{g_}}} || 네임스페이스의 글로별 변수 || || {{{m_}}} || 클래스의 멤버 변수 || || {{{s_}}} || 클래스의 static 변수 || || {{{c_}}} || 함수의 static 변수 || 다른 타입 접두어 앞에 붙인다. (예: {{{m_lpszName}}} - 클래스 멤버 변수인 문자열 포인터) 이 접두어들은 당연히 private 멤버에 사용하는 것이다. 절대 public으로 오픈하지 말 것. ==== Windows API ==== || 접두어 || 데이터 타입 || || {{{h}}} || 리소스 핸들 ({{{HWND}}}를 제외한 모든 HANDLE 타입) || || {{{hwnd}}} || Windows 핸들 || Windows API 문서를 보면 {{{wParam}}}과 {{{lParam}}}이 지겹게 등장하는데, 접두어대로 {{{wParam}}}은 word나 dword 기반, {{{lParam}}}은 int나 long 기반이다. === Apps Notation === 데이터 타입이 아닌, 데이터의 논리적 상태를 명시하는 방식이다. 변수 뿐 아니라 함수에도 사용가능하다. 사실상 이쪽이 시모니가 의도한 진짜 사용법이라고 볼 수 있다. <조엘 온 소프트웨어>로 유명한 조엘 스폴스키도 블로그에서 이러한 점을 지적하며 잘 작성된 헝가리안 표기법을 사용하면 코드에서 "버그가 스스로 드러나는" 코딩을 할 수 있다고 주장했다.[[https://www.joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong/|#영어]] 의미에 따라 접두어가 붙기 때문에 의도치 않은 대입 등을 바로 알 수 있기 때문이다. [[https://msdn.microsoft.com/en-us/library/aa260976(VS.60).aspx|시모니가 MS에서 작성한 헝가리안 표기법 제안]]을 봐도 단순히 기계적으로 타입명을 붙이라고는 하지 않았다. 접두사 {{{ch}}}에 대한 설명을 보면 "char형. 일반적으로 아스키 문자"라고 되어 있다. 즉, "ch가 붙은 변수는 문자라는 '의미'이므로 문자 말고 다른 값이 들어가지 않도록[* [[C(프로그래밍 언어)|C언어]]에서는 문자도 그냥 1바이트 정수로 취급하므로 숫자를 대입해도 아무 이상이 없다.] 주의하며 코딩해라"라는 의미. ==== 예시 ==== 타입이 아니라 의미에 따라 이름을 붙이는 방법이기 때문에 정해진 규칙이 없다. 이런점이 Apps Notation을 배우기 어렵게 하고 Systems Notation이 대세가 된 이유이기도 하다. || 접두어 || 의미 || || {{{n}}} ||Count 변수 || || {{{d}}} ||두 값의 차이를 담는 변수 || || {{{us}}} ||안전이 확인되지 않은 변수(UnSafe).[* 사용자 입력값을 그대로 받아서 무결성 검증이 되지 않았고(나이에 음수를 넣었다거나), [[SQL injection]]처럼 해킹의 의도를 가진 문장일수도 있다.] || || {{{s}}} ||안전이 확인된 변수(Safe) || || {{{Locked}}} ||함수의 접미사. 스레드 안전하지 않은 함수기 때문에 사용하기 전에 [[세마포어|Lock]]을 잡아야 한다 [[안드로이드(운영체제)|안드로이드]]에서 사용된다. || 간단히 예를들면 {{{#!syntax java int sValue = usValue; // Unsafe 값을 Safe 변수에 바로 넣었다. 양변의 의미가 다르므로 문제가 있는 코드 sValue = sCheck(usValue); // us값을 체크해서 s로 바꿔주는 함수 sCheck를 거쳤다. 양변이 모두 s이므로 문제없는 코드 sValue = sCheckLocked(usValue); // 의미는 맞지만 Locked 함수를 쓰기 전에 락을 걸지 않았다. 멀티스레드에서 동작시 문제가 생길 수 있다. }}} == 장점 == * 데이터 타입을 변수명에서 바로 추정할 수 있다. * IDE가 없을 때 작업하는 경우 (특히 vi나 emacs로 터미널에서 작업할 때) 여러모로 유리해진다. * 같은 의미를 가지는 서로 다른 타입의 변수가 있을 때 이름 충돌을 방지할 수 있다. == 단점 == * 아이러니하게도, 코드를 단번에 파악하기 힘들어진다. * 변수나 함수 인자의 이름을 기억하기가 힘들다. * '''데이터 타입이 바뀌면 변수 또는 함수 인자의 이름을 바꿔야 한다.''' 리팩토링을 지원하는 IDE가 없으면 지옥도가 펼쳐질 것이다. 특히 [[PHP]]나 [[JavaScript]], [[Python]], [[Ruby]] 같은 동적 타입 언어와의 궁합은 최악. * [[C(프로그래밍 언어)|C]]/[[C++]]일 경우 언어 명세에서 데이터 타입의 크기를 강제하지 않은 바람에 '''시스템 아키텍처에 따라 데이터 타입의 크기가 다르다는 무시 못할 문제가 있다.'''[* 과거 16비트에서 32비트로의 전환기에도 헬게이트가 열렸었으며, 2010년대는 소프트웨어가 [[AMD x86-64]]로 이관하는 과정이 진행 중이기 충분히 생길 수 있는 문제이다.] 예를 들어 {{{w}}}는 16비트일까? 32비트일까? 64비트일까? ~~묵념~~ * 같은 의미를 가지는 서로 다른 타입의 변수가 있을 때 이것들을 왜 선언했는지를 잊어버렸다면 [[혼돈! 파괴! 망가!]]가 연출된다. ~~주석은 이럴 때 다는 것이다.~~ == 몰락 == 디스플레이 화면이 커지면서 한 눈에 볼 수 있는 코드의 양이 많아지고, IDE가 눈부시게 발전하면서 마우스 커서만 올리면 해당 변수의 데이터 타입이 뙇!하고 나오는 덕에 헝가리안 표기법은 바로 구식으로 변하고 말았다. 애초에 헝가리안 표기법 자체가 정적 타입 언어가 대세인 시절에 나온 것이다 보니, 요즘처럼 파이썬이나 자바스크립트처럼 동적 타입 언어가 유행하는 시기에는 맞지가 않다. 최근에는 대신 C++에서 클래스 멤버 변수인 경우에 이름 뒤에 {{{_}}}를 붙이는 정도로 간소화 해서 쓰는 경우가 있고, 데이터의 논리적인 상태를 나타내는 Apps Notation은 지금도 간간히 쓰이고 있다. == 관련 문서 == * [[https://en.wikipedia.org/wiki/Hungarian_notation]] * [[https://msdn.microsoft.com/en-us/library/aa260976(VS.60).aspx]] - 찰스 시모니가 MS에서 제안한 표기법 문서 (MSDN) * [[https://msdn.microsoft.com/en-us/library/aa378932(VS.85).aspx]] - MS 코딩 규칙 [[분류:컴퓨터]][[분류:프로그래밍]]