Python 시작!

Programming/Script Programming
2009. 5. 12. 12:27, Posted by ScottRhee
0. Intro 

웹에서는 자바스크립트가 쓰이고, 엑셀에서는 VBA가 쓰인다.
이것들의 공통점은 물론 스크립팅이 가능하다는 점이다. 

그럼 일반적인 OS의 셸에서는 어떤 스크립팅이 쓰일까?
VB스크립트? 배치파일? 셸스크립트? 
다 맞는 얘기지만 플랫폼 디펜던트한 문제가 있다.
파이썬은 여기에 대한 해결책을 제시하는 멋진 대안이다. 

물론 사실은 파이썬은 스크립팅 언어라고 불리기에는 억울할 정도로 기능도 많고
UI 함수 제공은 물론.. 외부 라이브러리, 심지어는 MFC까지 연동이 될 정도니
어디가서 파이썬이 스크립팅 언어라고 하면 돌 맞을 일이지. 스크립팅 언어로 누군가 분류를 할 수는 있을지 몰라도.. 

하지만 파이썬은 전문적인 프로그램 제작보다는.. 역시 일반적인 프로그래밍 언어로 작성하기에는 너무 거추장스럽거나 비효율적인 일을 하는 데에 더 적합해 보인다. 엄청 유연하거든! 커맨드라인을 제공하고, 이것저것 마구 휘두를 수 있는 점으로 치면 과거 퀵베이직을 보는 듯한 그런 느낌이지만 시대가 시대이니만큼 훨씬 강력한 기능들을 많이 제공하고 있다. 뭐랄까, 21세기의 베이직이랄까. 

복잡한건 다 빼버리고, 하고싶은 일은 라이브러리 등의 형태로 다 갖다 쓸 수 있고, 그러면서도 객체지향 언어를 배울 수 있으니, 과연 지금의 개발자라면 꼭 가지고 있어야 할 능력이 아닐까 싶다. 간단한 예제를 몇개 짜보면서, 비슷한 일을 C++로 하려면 얼마나 손이 많이 갔을까 생각해보니 파이썬의 위력을 실감할 수 있었다. 그리고, 직접적인 연관성은 없겠지만 NSIS를 처음 접했을 때처럼 개발환경 구동 후 실제 프로그램이 완성되기까지의 절차가 매우 간편하며 문법이 매우 쉽고 오로지 로직에만 신경쓸 수 있게 해주는 점이 참 마음에 든다. 

아직까지도 파이썬이 뭔지 잘 모르겠다고? 걍 개발환경을 제공하는 인터프리터 언어라고 일단 이해해놓자! (물론 시대가 시대이니만큼 인터프리터 언어에만 그치지 않을거라는건 누구나 예상할 수 있겠지만.. 여튼..) 그리고 설치파일 하나만 설치하면 모든 준비가 끝일 정도로 미치도록 간단하다고 생각하자! 그리고 혹시 NSIS를 해본사람이라면 그거만큼 간단하다고 보면 된다. Just Do It! 

1. 시작하는 방법 

파이썬 공식 홈페이지. 새 창으로 열자. 

그리고 나같은 윈도 사용자는 왼쪽의 Quick Links 메뉴 밑에 있는 Windows Installer를 다운로드하면 된다. 일단 정말로 웹서핑에 자신이 없는 분을 위해 3.0.1버전의 인스톨러 URL을 직접 적어놓는다. 하지만 언제 주소와 버전이 바뀌거나 파일이 없어질지 모르니 홈페이지를 직접 찾아가는 것을 권장한다. 

플랫폼 인디펜던트한 언어인만큼 타 OS에서도 설치방식이 크게 다르지는 않으리라. 버전은 2.x대와 3.x대가 있는데, 예제 소스를 비교해본 결과 문법과 라이브러리가 좀 바뀐 느낌이다. 기존 자료를 많이 활용해야 한다면 2.x를, 남이 짜놓은 것보다는 처음부터 스스로 공부하며 배울 사람은 아무래도 향후에 많이 쓰일 것으로 예상되는 3.x를 추천하는 바이다. (현재는 3.x가 최신 버전인 듯.) 나는 3.x를 설치했다. 검색해서 나오는 예제 소스들 대부분이 바로 실행이 되지 않고 살짝 변경을 해줘야만 했다. 하지만 라이브러리 소스라든지, 키워드 도움말 등에서 기존 버전과 달라진 점을 친절히 소개하고 있으니 웬만한 경우에는 큰 문제는 없을 듯. 

암튼 아무생각없이 MSI로 된 인스톨러를 실행하면 끝.
VS같이 복잡한 컴파일러 설정이라든지.. 리눅스 C컴파일러처럼 환경설정을 해야한다든지.. 이런거 하나도 없다. 나중엔 필요할지 모르나 개발환경에서 예제 실행하고 개발해보고 이러는 데에는 별도의 조작이 필요없다. 파이썬이 설치되는 기본 경로는 C:\Python30 이다. 옛날 터보C를 생각나게 하는 경로이름이 아닐 수 없다. 

2. 개발환경 불러오기 (Windows 기준) 

시작메뉴를 불러보면 파이썬 그룹이 새로 생긴걸 알 수 있다. 그중에 IDLE라고 하는것과, Python(Command Line)이라는 것이 있는데, IDLE라는놈을 실행시키면 마치 리눅스의 콘솔창을 띄운 것처럼 셸이 하나가 뜬다. 흠.. 뭔가 입력해보고 싶지 않은가. 도움말은 help()를 치면 된다. 그냥 help라고 치면 안나옴. -_- 참고로 help()명령 입력시 마치 리눅스의 man페이지처럼 따로 또 프롬프트가 나타나는데, 거기선 q명령을 입력해야 다시 원상태로 돌아올 수 있다. 

Python 3.0.1 (r301:69561, Feb 13 2009, 20:04:18) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> 

8비트 컴퓨터의 베이직이나, GW-BASIC을 만져본 사람이라면 이해하기 쉬울 텐데, 인터프리팅 셸이다. 즉, 직접명령어 방식으로 명령어를 실행할 수가 있고, 워드프로세서처럼 새창열기를 하면 따로 소스 창이 열려서 이걸 통해 프로그램을 작성하고 실행할 수도 있게 되어 있다. 직접명령어 모드에서 이것저것 예약어들을 시험해볼 수 있고, 변수 타입이라든지 문법 연습 등에도 제격이다. 다만, 인터프리터 셸이라 그런지 일반적인 도스창이나 셸 창보다는 많이 느린 게 흠. 직접명령어 방식으로도 라이브러리 임포트 등이 가능하니, 라이브러리를 테스트한다든지, 뭔가 아이디어가 났지만 프로그램을 짜기까지는 귀찮을 때, 정말 유용하게 쓸 수 있다. 

8비트 베이직에서는 라인넘버를 주고 소스를 입력했고, 퀵베이직이나 QB에서는 직접명령어 창과 간접명령어 창이 분리되었으며, 비주얼스튜디오에서는 간접명령어창만 있고 프로그램 실행시의 결과는 새로 뜨는 창에서만 볼 수 있는 형태였다면, 요놈은 직접명령어창과 output창이 합쳐졌고 소스 편집은 별도의 창에서 하는 형태라고 볼수 있겠다. 출력창이 고정되어 있기 때문에 콘솔모드 프로그램 작성할때 아주 편하다! 암튼 이것저것 명령어를 시험해 보자.

>>> a = 1000   
>>> type(a)      
<class 'int'>
>>> b = "ZZZ"  
>>> a = (str)a
SyntaxError: invalid syntax (<pyshell#13>, line 1)
>>> a = str(a)
>>> a
'1000'
>>> type(a)
<class 'str'>
>>> "ABCDE".find('C')
2

보아하니 문법이 자바와 베이직과 C의 특징을 모두 지녔다. 모든 변수는 내부적으로 클래스로 인식됨을 알 수 있으며, 상수처럼 보이던 녀석도 각자의 타입에 맞는 메서드 호출을 할 수 있었다. 베이직처럼 형변환 예약어를 통해 캐스팅 비스무레한걸 할 수 있으며 그것을 자기 자신에게 할당하는 순간 변수 자체의 타입도 변화함을 알 수 있다. 그리고 C스러운 캐스팅은 되지 않는다. Syntax Error 참 오랜만에 본다.. 베이직 프로그램 할때의 내 친구였는데.. 

키워드에서 대소문자 구별을 하는 점, 함수 호출시 꼬박꼬박 괄호를 써야 하는 점은 C스럽지만, 세미콜론이 필요없다든지 형변환이 자유자재라든지 이런 점은 베이직을 빼다 박았다. 이런 절묘한 특성상, 기존에 어떤 프로그래밍을 했었던 사람이라도 파이썬에 적응하기가 어렵지 않을것 같다는 생각이 든다. 모든 게 딱 중간이다. -_- 귀찮아 때려치울래 하는 생각이 들기 직전에 꼭 하나씩 친근한 문법들이 나와준다. 

>>> if 1000>100 :
print ("당연히 더 크지 임마")
(이 부분은 그냥 엔터를 한번 더 누른다)
당연히 더 크지 임마 (결과)

이것도 이대로 입력해보자. 다중라인이 필요한 직접명령어는, 바로 결과를 내거나 에러를 뿌리지 않고 명령이 끝날때까지 프롬프트를 다시 내지 않는다! (직접 해보면 알겠지만, printf문이 끝나고 엔터를 치면 빈칸이 하나 더 나온다. 여기서 한번 더 엔터를 쳐야 결과값을 찍는다. 아시다시피 블럭이 언제 끝날지 모르니까 그런 것.) 와우 똑똑하구나. 
인용문에서는 확인하기가 어려우나, 파이썬은 인덴팅에 독특한 방식을 사용한다. 일단 문법자체는 보기 어렵지 않을것이다. C나 베이직에서 맨날 하던 그거니깐. C와 비교하면 괄호가 없고, 베이직과 비교하면 then대신 콜론이 들어갔고 if문에 대문자를 쓸 수 없다. 파스칼 문법은 잘 모르지만 파스칼 소스에서 콜론을 많이 봤는데 그 생각도 좀 난다. 
허나, 두번째줄 print문을 입력할때면 자동으로 탭이 한칸 입력(인덴팅)되어 있는데, 간접 명령어, 즉 소스 코딩을 할 때에도 이것을 지켜줘야 한다. C나 베이직처럼 단순히 가독성을 위해서 임의로 하는게 아니고, 아예 저 인덴팅을 가지고 블럭 구분을 한다는 것이다. C에서는 브레이스({})가, 베이직등 일부 언어에서는 endif 등의 예약어가 하는 일을 요놈은 아예 인덴팅으로 구현해 버렸다. 이 결과, 가독성 하나는 끝내준다. 컴팩트한 코딩을 못하게 되는건 좀 답답하지만.. 개인적으로 모든 프로그래밍의 미덕은 가독성이라 생각하기에, 파이썬이 주로 쓰이는 용도를 감안하면 아주 좋다고 본다. 

3. 예제 프로그램 하나 해보자 

인터프리터 셸에서 File 메뉴를 열고, "New Window"를 열어본다. 그냥 빈 창이 하나 뜰 것이다. 보기엔 메모장같이 생겼지만 그래도 신택스 하일라이팅 등 개발툴스런 기능은 대부분 들어 있다. VC사용자에게 익숙한, 객체 변수명에 캐럿을 갖다놓고 누르는 Ctrl-Space기능도 그대로 먹는다. 그래도 VisualAssist수준의 기능은 기대하지 말자. ㅎㅎㅎ 

# 네이버 환율에 접속해서 환율 정보를 가져오는 프로그램
import urllib.request
f = urllib.request.urlopen('http://bank.naver.com/index/exchange.nhn')
str1 = str(f.read())

# USD를 찾아라
substr_point = str1.find('USD') - 30
value_start_point = str1.find('\'', substr_point)
value_end_point = str1.find('\'', value_start_point +1)
if value_start_point > 0 and value_end_point > 0 : 
    print (str1[value_start_point + 1:value_end_point - 1])

새로 뜬 창에 위 블럭을 그대로 입력해본다. (2.x버전 사용자는 소스를 좀 바꿔야 한다. 사실 위 소스 자체가 2.x버전을 가져다가 수정한 것이다.) 실행은 F5이다. 새로 작성한 소스이므로 세이브를 요구할테니 적당한 폴더에 저장한다. (나같은 경우는 Samples 폴더를 C:\python30폴더 밑에 만들어서 거기에 넣었다.) 확장자는 *.py인데, 과거 *.bas파일의 역할을 한다고 보면 틀림없다. ㅋㅋ 

실행에 성공했으면, 네이버 환율정보 페이지 소스가 크게 바뀌지 않는 한, 인터프리터 창에 현재의 원달러 환율이 표시될 것이다. 소스가 바뀌었어도 URL이 변하지 않는 한, 쓰레깃값이라도 화면에 표시될 것이다. 와우, 환율 많이 내렸네. 

>>> ================================ RESTART ================================
>>> 
1242
>>> 

이런거 C++로 짜려면 진짜 겁나게 귀찮겠지? 간단한거 하나 짰는데 용량도 엄청 차지할거고.. 파이썬이 어떤 용도로 많이 쓰이게 되는지 바로 느껴지게 될것이다. 위에 ==== RESTART === 요것은 기존에 직접모드 명령들때문에 프로그램 수행에 지장을 주는 것을 막기 위해 내부 인터프리터 가상머신을 자동으로 재시작하는 것이다. (에뮬레이터 게임 해본 분들은 어떤 상황인지 이해가 될 듯.) 직접모드에서 이것저것 하다가 뭔가 꼬인것같을때 강제로 할수도 있는데, 간단히 Ctrl-F6을 누르면 된다. 

예제 소스의 해설을 하는 것으로 오늘의 포스팅은 마치도록 하겠다. 

4. 예제 프로그램 해설 (진짜 별거 없지만..)

import urllib.request
f = urllib.request.urlopen('http://bank.naver.com/index/exchange.nhn')
str1 = str(f.read())

import 명령은 NSIS를 써본사람이라면 알고있을 것인데 거기서 쓰는 import 명령과 거의 똑같다고 보면 된다. 자바하고도 비슷하고.. VB에도 저런게 있었던것 같다. C++하고는 좀 다르지만.. 
여기서 urllib.request 라는 것은, urllib라는 큰 라이브러리 꾸러미 안에 있는 request라는 객체를 이용하겠다는 얘기다. C:\Python30\Lib\urllib 폴더에 가보면 request.* 파일들이 있는데, 함수 원형이 선언된 *.py파일과, 미리 중간 단계 파일로 컴파일이 되어진 *.pyc파일이 있음을 알 수 있다. py파일을 열어보면 함수 선언과 도움말을 볼 수 있고, pyc파일은 이진 코드라 제대로 확인이 되지 않는다. C에서의 헤더파일과 lib파일의 역할이랄까. 암튼 구조상 내가 만든 라이브러리를 넣기도, 그리고 남에게 전달해주기도 무지하게 편하겠다는거 알 수 있다. 게다가 플랫폼 인디펜던트니 뭐. 

암튼 저 urllib.request라는 객체 안에 있는 urlopen이라는 함수가 뭔짓을 하는지는 눈짐작으로도 알 수 있다. 웹페이지에 있는 내용을 GET등의 명령을 통해 텍스트로 긁어올 것이다. 그리고 그것을 f라는 객체로 받아온다. f객체는 보기에는 꼭 파일같지만, 실은 urllib에서 정의한 자체적인 타입을 이용하고 있다. f.read는 해당 URL을 읽어서 바이너리 타입으로 리턴하게 되는데(VB에 있는 BYTE타입을 생각하면 딱), 우리는 읽어들인 데이터가 일반 텍스트라는것을 알고 있고 바이너리는 문자열 타입이 아니어서 문자열 메서드를 사용할 수 없으므로 str예약어를 써서 일반적인 스트링으로 강제 변환해 주었다. 이제 str1에는 저 URL의 소스가 그대로 들어있게 되었다. 웹브라우저로 URL을 직접 쳐보거나 소스 보기를 해보면 알겠지만 저 소스에는 환율 정보가 모두 들어있으므로 그 안에 있는 데이터중 우리에게 필요한 것을 파싱하기만 하면 되는 것이다. 

# USD를 찾아라
substr_point = str1.find('USD') - 30
value_start_point = str1.find('\'', substr_point)
value_end_point = str1.find('\'', value_start_point +1)
if value_start_point > 0 and value_end_point > 0 : 
    print (str1[value_start_point + 1:value_end_point - 1])

"#" 요거 나왔다. 이거 아주 흔히 쓰이는 주석 라인 표시다. 여기서도 주석으로 사용되고 있다. 그 다음 라인은, URL의 텍스트를 분석해 원달러 환율을 뽑아내는 것인데, URL의 소스를 확인해보면 대충 이런식이다. (필요한 부분만 발췌)

......
<form onSubmit="javascript: calcCurrency()" name="exchange"> 
<div class="excalc_bx"> 
<select id="sel_normal1" name='from' style='width:129px'> 
<option value='1'>대한민국 (KRW)</option> 
<option value='1241.5'>미국 USD</option><option value='1878.27'>영국 GBP</option><option value='1067.04'>캐나다 CAD</option><option value='1122.01'>스위스 CHF</option><option value='160.19'>홍콩 HKD</option><option value='158.46'>스웨덴 SEK</option><option value='945.28'>호주 AUD</option><option value='226.72'>
........

원달러 환율은 "USD"라는 문자열 앞쪽에 기입이 되고 있다. 그래서 USD라는 글자를 찾아서 대충 30문자 앞의 인덱스를 먼저 얻어왔다.
그리고 이상태에서, 해당 URL의 소스에 의하면 원달러 환율은 작은따옴표에 의해 둘러싸여 있다. 파이썬에서 작은따옴표 표기는 마치 C에서처럼 \' 를 사용하고 있다. find명령으로 숫자가 들어가 있는 인덱스를 적절히 구해온다음 이것을 print명령으로 출력한다. 

4. Outro

지금까지 본 것처럼, 간단한 노가다 몇줄로 간단히 웹페이지에서 원하는 정보를 쏙 뽑아올 수 있었다. 글로 써놔서 이리 길지, 파이썬에 일자무식이라도 단 3분만에 이 단계까지 도달할 수 있다. 본문에선 인터프리터를 사용한 방법만 나와있지만, 관련 사이트를 조금만 뒤져보면 작성한 프로그램을 독립 실행형으로 분리하여 일반 윈도 프로그램처럼 실행하는 방법을 쉽게 찾을 수 있다. (상황이 되면 이에 관한 포스트를 쓸 수 있을지도 모른다.) 

이제 왜, 웹페이지 모니터링 툴이 파이썬으로 많이 작성되어 있는지 이해할 수 있을 것이다. 각종 언어와의 연계도 잘 되어 있는 편이라, C++로 짠 라이브러리 등을 파이썬에서 호출해서 쓰는 등의 기법도 얼마든지 가능하다. 이런 작업을 포함하여, 파이썬의 간편함과 직관성과 라이트함, 그리고 윈도와 리눅스는 물론 Java VM이나 닷넷까지도 지원하는 엄청난 플랫폼 비의존성은 개발자에게서 수많은 노가다 작업을 덜어주고 있다. 이 문단을 보면서, 지금까지 나의 밥벌이라고 생각했던 특정 툴을 통해 간단한 작업의 덩치를 어쩔 수 없이 불려가며 작업했던 삽질들이 주마등처럼 스쳐지나간다면 당신은 파이썬을 잘 시작한 것이다. 이건 정말 오랜만의 상쾌함이다. 


:

데이터를 자동으로 정렬해서 저장한다 - CSortedArray, CSortedArrayEx

Programming/C/C++ Programming
2008. 8. 24. 23:01, Posted by ScottRhee

특정 타입의 데이터를 저장하긴 해야겠는데, 이것을 자동으로 정렬해가면서 저장하고 싶을 때가 있습니다. 이럴 때 사용하는 자료구조입니다. 템플릿 형태로 되어 있기 때문에 타입만 지정해주면 됩니다.


이 템플릿 클래스의 원래 출처는 이곳입니다 : http://www.naughter.com/sortedarray.html


남의 소스를 왜 자기것처럼 업로드했냐고요? 그것은, 이 소스의 최신버전은 VS2005 이상만 지원을 하기 때문입니다. 이 포스트에 올라온 버전은, VS2003에서도 쓸 수 있도록 약간 수정을 가한 버전입니다. (디버그 관련 명령어 하나만 바꾼 거지만.-_-) 첨부파일을 참고하세요. 그 부분 이외에 다른 Copyright부분이라든지 코멘트 부분 등은 전혀 손을 대지 않았습니다.  


내부 구조는, MFC를 이용하는 프로젝트일 경우 CArray템플릿을 이용하며, 그렇지 않을 경우 CSimpleArrayEx를 이용하도록 되어 있습니다. (CSimpleArrayEx는 ATL의 CSimpleArray를 확장하여 삽입 기능을 추가한 버전인데, ATL 라이브러리쪽으로 작업을 하시는 분은 분은 위의 출처 링크로 가서 CSimpleArrayEx의 소스를 받아서 추가하시면 ATL버전을 쓸 수 있습니다.) 


CSortedArray는 자체적으로 Binary Tree를 사용하여 정렬과 검색을 빠르게 실시합니다. 입력과 동시에 정렬이 자동으로 되기 때문에, 따로 정렬 알고리즘을 구현하지 않아도 된다는 결정적인 장점이 있습니다. 다만, CArray를 상속한 것이기 때문에 직접 어레이에 값을 쓰는 메서드도 오픈이 되어 있어서, 수동으로 정렬을 하는 메서드도 따로 준비를 해두었네요.


사용 방법은 무척 간단합니다. 메모리 관리 클래스를 사용해보신 경험이 한번이라도 있다면, 사용상 전혀 무리가 없을 만한 수준입니다. 다만, 자료구조에 담기는 데이터가 항상 단순 수치인 것은 아니기 때문에, 서로의 값을 비교하는 룰(비교함수)을 제공해야 합니다.


이 라이브러리에는 버전이 두 개가 있습니다. CSortedArray와 CSortedArrayEx가 그것인데요, 기능적인 부분은 같고, 다만 CSortedArray는 일반적인 콜백 함수로 비교 함수를 지정하며, CSorrtedArrayEx는 콜백함수가 아닌 콜백클래스(Functor)를 이용하는 점이 다릅니다. 펑터에 대해서 궁금하신 분은 http://www.newty.de/fpt/functor.html 링크를 참조하시기 바라며, 간단히 설명드리면 컴파일타임에 메서드가 인라인 처리되어 빠른 속도를 낼 수 있는 처리방법이라고 생각하시면 됩니다. 콜백으로 펑션과 펑터를 사용한다는 차이점을 제외하면, 나머지 기능은 완전히 동일합니다. 다음은 콜백 구현의 예입니다. 왼쪽이 펑션, 오른쪽이 펑터입니다.


사용자 삽입 이미지


왼쪽 함수야 따로 설명드릴건 없을것 같고.. 오른쪽 펑터 버전은 함수 호출에 해당하는 오퍼레이터를 재정의해서 빠른 속도를 꾀하고 있군요. 실제 개발자가 테스트해본 바에 의하면 훨씬 속도가 빠르다 합니다. 펑터의 장점이지요. 사용법이 많이 어려운 것도 아니니 펑터 버전의 사용을 권장합니다. 다만, VS2008에서는 컴파일러 최적화 기능이 좋아져서 거의 차이가 없어진다고는 하는군요. 창피한 일이지만 함수 호출도 오퍼레이터로 처리되는줄은 미처 몰랐습니다^^;;


펑터 버전, 즉 CSortedArrayEx를 가지고 간단한 예제 프로그램을 만들어 보겠습니다. 맨 윗줄에 있는 CompareIntsClass는 물론 앞서 적어둔 비교용 콜백 펑터입니다. 당연하지만 소스에 그것을 먼저 적어주셔야 합니다.

CSortedArrayEx<int, int&, CompareIntsClass> idata;

 int d = 7;  idata.OrderedInsert(d);
 d = 3;  idata.OrderedInsert(d);
 d = 4;  idata.OrderedInsert(d);
 d = 5;  idata.OrderedInsert(d);
 d = 2;  idata.OrderedInsert(d);

템플릿의 파라미터는 각각 저장할 값의 타입, 참조 타입, 그리고 비교펑터로 선언하게 되어 있습니다. 그리고 OrderedInsert가 데이터를 정렬시켜가며 입력하는 메서드입니다. 아주 간단하지요? 이렇게 데이터를 무작위로 넣어도, 어레이에는 항상 0번째 인덱스부터 오름차순으로 데이터가 정렬되어 저장된다는 겁니다. 즉, 아래 루틴을 루프로 돌리면 작은 수부터 출력이 잘 이루어지지요. 2, 3, 4, 5, 7 이렇게 출력된다는 겁니다. RemoveAt(0)으로 값을 빼내도 그즉시 다시 자동정렬이 돼서 옆에 있던 값이 채워집니다.

 int intData = idata.GetAt(0);

 printf("%d\n", intData); idata.RemoveAt(0);

자, 그럼 이것을 어디에 이용하느냐? 저는 이것을 서버-클라이언트 이벤트 처리에 이용했었습니다. "특정 시각에 해야 할 일"을 처리하는 용도로 사용했지요. 시각을 수치화시켜서(GetTickCount등을 이용) 위 자료구조에 집어넣으면, 가장 빠른 시간에 해야 할 일을 항상 찾아낼 수가 있습니다. 현재 시간과 비교해서 맞는 시간에 해당하는 일부터 처리하고, 현재 시각에 맞는 일이 아직 없으면 기다리면 되니까 편리하게 이용할 수가 있는 거지요. 기타, 데이터 입력이 런타임으로 계속 일어나는 그런 상황에서의 정렬에 쓰시면 됩니다. 하지만, 데이터 입출력 시점이 명확하게 정해진 상황에서의 정렬이라면 일반적인 정렬 알고리즘을 쓰는 게 더 좋은 방법이 될 수도 있겠죠.



결론


용도 : 우선순위, 또는 자동정렬이 필요한 작업

장점 : 추가적인 정렬 함수 호출 없이도 항상 정렬된 결과를 보장해준다. Binary Tree를 이용하기에 따로 정렬을 하지 않으므로 퍼포먼스가 뛰어나다. Functor 콜백을 선택적으로 제공하여 상황에 따라 편리하게 사용할 수 있다.

단점 : 중복 값이 있을 경우에는 탐색 기능만으로는 원하는 오브젝트를 바로 찾아낼 수 없다. ATL도 MFC도 이용할 수 없는 환경에서는 쓸 수 없다. (..단점이라 하긴 좀^^)

: