피씨컴의 기울어진 공관

'프로그래밍'에 해당되는 글 77건

  1. 2013.06.19 DX 기본수학 (2)
  2. 2013.06.19 Dx 기본 수학 (1)
  3. 2013.04.17 API 4장 1
  4. 2013.04.16 API 3장
  5. 2013.04.16 API 2장
  6. 2013.04.16 AIP 1장
  7. 2013.04.09 degree(도), π(파이), radian(라디안) 그리고 c/c++ 삼각함수 1
  8. 2013.03.21 자료구조 1
  9. 2013.03.20 함수 호출규약
  10. 2013.03.20 정리정리

● 내적

- 코사인의 법칙을 이용하면 UㆍV = ||U||||V||의 관계를 발견할 수 있으며 이는 두 벡터간의 내적이 벡터크기 배율을 가진 벡터 간 각도의 코사인임을 알 수 있다. 따라서 U와 V가 모두 단위 벡터일 경우 UㆍV는 두 벡터 간 각도의 코사인이 된다.

 

 

 

- 만약 UㆍV == 0  이라면 UㅗV 이다

- 만약 UㆍV >0  이라면 두 벡터 간의 각도는 90도 보다 작다

- 만약 UㆍV <0  이라면 두 벡터 간의 각도는 90도 보다 크다

 

- 단위 벡터일때만 성립

- 지가 알아서 단위 벡터를 만들어 주진 않음

- 결과 스칼라

 

FLOAT D3DXVec3Dot( CONST D3DXVECTOR3 * pV1, CONST D3DXVECTOR3 * pV2)

리턴 : 결과를 리턴

인수 1 : 왼쪽 피연산자

인수 2 : 오른쪽 피연산자

 

 

● 외적

- 스칼라로 계산되는 내적과는 달리 외적은 벡터로 계산

- U와 V 두벡터의 외적을 수행하면 다른 벡터인 P를 얻으며 이는 U와 V에 서로 직각을 이룬다 즉 P는 U에 직각이며 P는 V에 직각이다.

 

 

- 성분형식

px : (UxVz-UzVy)

py : (UzVx-UxVz)

pz : (UxVy-UyVx)

- 외적 UXV=P 벡터는 U와V에 모두 직각이다.

- 항상시계방향을 생각해야한다.

- 서로 바뀌면 역방향이 된다.

- 노간== 법선?

-외적이 교환적이지 않다.

- 외적을 수행하는 순서는 우리가 얻을 결과가 p나 -p중 어떤것이 될지 결졍한다 다른말로 하면 UXV=-(UXV) 이다

 

D3DXVECTOR3 * D3DXVec3Cross(D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 * pV1,CONST D3DXVECTOR3 * pV2)

인수 1: 결과를 리턴한다.

인수 2 : 왼쪽 피연산자

인수 3 : 오른쪽 피연산자

 

 

● 행렬

- mxn 행렬은 m행과 n열을 가지는 일반적인 수의 배열이다. 행과 열의 수는 행렬의 차원을 결정하며, 행렬의 항목은 이중 아래첨자로 행과열 번호를 적어 표기할 수 있다. 여기서 첫번째 아래 첨자는 행을 지정하며 두번째 아래 첨자는 열을 지정한다

- 가로 행 / 세로 열

- 행렬끼린 차원이 같아야 연산이 가능하다

- 교환법칙이 성립되지 않는다.

- 벡터는 행렬의 일종이다 (1행, 3열)

 

● 곱

- 왼쪽 피 연산자의 열수와 오른쪽 연산자의 행수가 반드시 같아야 한다

 

2 X 3     3 X 3 == 0

3 X 3     2 X 3 == X

- 교환 법칙이 성립되지 않는다.

 

● 항등행렬

- 중심 대각선요소의 값은 모두 1이며 나머지 값은 모두 0인 행렬

- 피연산자 * 항등행렬 = 피연산자

- 곱셈의 항등성을 가진다 (mI=IM=M)

- 행렬계의 1

- 어떤 행렬에 항등행렬을 곱하면 어떤행렬이 나옴

- 교환법칙 성립

- 항등 정방행렬 == 0

 

● 역행렬

- 행렬에는 나누기와 비교할 수 있는 연산은 없지만 곱하기와 반대의 의미를 가지는 역 연산이 존재한다

- 정방행렬 만이 역행렬을 가질수있다 즉 역행렬에 대해 이야기 할 때는 정방행렬에 대해 이야기 하는 것과 같다.

- nXn 행렬 m의 역행렬을 가지지는 않는다

- 행렬과 역행렬을 곱하면 항등행렬을 얻는다

 

- 행렬은 자신의 역행렬과 곱할때는 상호 교환적이다.

'프로그래밍 > 공부' 카테고리의 다른 글

Dx 기본 수학 (1)  (0) 2013.06.19
API 4장  (1) 2013.04.17
API 3장  (0) 2013.04.16
API 2장  (0) 2013.04.16
AIP 1장  (0) 2013.04.16
Posted by 피씨컴

● 벡터

- 길이와 가르키는 방향( 벡터는 양도 양이지만 방향) vector(힘의 세기, 방향)

- 위치는 벡터의 속성이 아님(위치를 가끔 담을수도 있는데 그건 바로 Point)

-  point(위치를 표시) : 좌표 시스템 내의 한 위치를 나타냄

- u벡터와 v 벡터는 동일하다.

 

● 스칼라 : 갯수

 

● D3DVECTOR3

- 3공간 내의 벡터를 표현

- 벡터를 담으면 벡터 point를 담으면 포인트, 단지 자료형일 뿐

- sizeof(D3DVECTOR3) == 12 이다

※ 보통 D3DVECTOR2,3,4가 있고 지금 당장 3을 쓰지만 나중에는 4를 많이 쓰게 될 것이다. 또 3을 쓰더라도 내부적인 연산에 있어서는 4를 이용한다.

 

● 좌표계

- 왼손좌표계

눈이기준 모니터 쪽으로 들어가는것이 + z

오른쪽이 +x

위쪽이 +y

 

openGL은 오른손 좌표계

 

● 표준 기저 벡터 : x,y,z축을 따라 진행하는 벡터

 

● 단위벡터 : 크기로 1을 가지는 벡터

 

● 0벡터 : 벡터의 모든 성분이 0인 것

 

● 벡터상등 : 두 벡터가 동일한 차원, 성분(길이,방향)이 같은 벡터를 말함

 

● EPSILON : 부동소수점의 부정확성을 위한 허용한계를 제공하는 것으로 두벡터를 비교해서 상등에 가까운지를 판단하게 하는 일종의 상수값

                    (실수의 경우 정밀도가 100%가 아니기 때문에 이런식으로 상동에 가까운지를 비교판단)

 

●  팁

1. 3D에서는 float를 쓰는게 좋음 double을 쓰면 느려짐 좋은게 아님  그기유는 float와 double의 연산정밀도는 차이가 4배정도 이기 때문에 double을 쓰면 그만큼 더 계산해야해서 느려짐 ㅇㅇ

 

 

● 벡터의 크기 계산

- 벡터의 길이

 

 

FLOAT D3DXVec3Length(CONSTD3DXVECTOR3 * pv)

 // 크기를 리턴하는 함수

리턴 값 : 스칼라값(크기)

인수 1 : 길이를 계산하려는 벡터

 

 

● 벡터의 정규화

- 벡터의 정규화

 

- 어떤 벡터를 u로 나눠주는것

- 벡터의 크기를 1로 만들어 단위벡터가 되도록 하는것

 

- D3DXVECTOR3 * D3DXVec3Normalize(D3DXVECTOR3 * pOut, CONST D3DXVECTOR3* pv)

인수 1: 결과

인수 2: 정규화하려는 벡터

 

'프로그래밍 > 공부' 카테고리의 다른 글

DX 기본수학 (2)  (0) 2013.06.19
API 4장  (1) 2013.04.17
API 3장  (0) 2013.04.16
API 2장  (0) 2013.04.16
AIP 1장  (0) 2013.04.16
Posted by 피씨컴

API 4장

프로그래밍/공부 2013. 4. 17. 00:24

● WM_CHAR메시지

윈도우즈 환경에서는 주로 마우스가 많이 사용되지만 아직까지도 컴퓨터의 가장 기본적인 입력 장치는 키보드이다. 키보드로부터 입력이 발생했을 경우 윈도우즈는 포커스를 가진 프로그램에게 키보드 메시지(WM_CHAR, WM_KEYDOWN)를 보내며 프로그램은 이런 메시지를 받아 키보드 입력을 처리한다.

 

즉 WM_CHAR 메시지는 입력된 문자의 코드를 wParam으로 전달하며 우리는 wParam의 값을 원어 사용자가 어떤 문자커를 눌렀는지를 알아낸다.

예를 들어 사용자가 ‘S’ 키를 눌렀으면 wParam은 S의문자 코드값인 0x53 이 전달되며 이 값을 그대로 화면으로 출력하면 문자 S가 출력될 것이다.lParam에는 비트별로 다음과 같은 복잡한 정보가 전달된다.

 

 

이 중 필요한 정보가 있으면 lParam을 참조하여 사용하고 필요없으면 wParam만 사용하되 WM CHAR 메시지에서 lParam의 정보들을 사용해야 할 경우는 드물므로 당장 관심을 가질 필요는없다. 메시지 별로 필요한 추가 정보는 함께 전달되는 wParamm,lParam을 통해 넘어오는데 wParam과
lParam을 사용하는 방법은 메시지별로 다르므로 추가 정보에 대한 사항은 따로 공부해야 한다.

 

 

포커스(Focus) : 입력 초점이라는 뜻이며 커보드 입력을 받아들일 수 있는 상태라는 뜻이다.

 

포커스를 가진 상태란 활성화되어 있고 현재 사용자가 쓰고 있다는 뜻인데 한 번에 오직 하나의 프로그램만 활성화된다 활성화된 윈도우는 타이틀 바의 색상이 다른 윈도우와 다르게 표시되는데 보통 파란색으로 표시된다 아무리 여러 개의 프로그램이 동시에 실행되는 멀티 태스킹 환경이라 하더라도 활성화될 수 있는 프로그램은 오직 하나밖에 없으며 활성화된 프로그램만 포커스를 가지고 키보드 입력을 받아들일 수 있다.

 

 

● 무효영역

WM_PAlNT 메시지 는 윈도우가 다시 그려져 야 할 필요가 있을 때마다 호출되는데 다시 그려져 야 할필요가 있다는 말은 무효영역(Invalid Region)이 있다는 뜻이다.

 

서로다른 윈도우가 겹쳐져있으며 어느 한 윈도우의 화면영역 일부가 다른 윈도우에 의하여 가려져있다 이상태에서 앞에서 가리고 있던 윈도우를 옮겨 가려졌던 부분이 드러나면 바로 이부분이 무효영역인것이다. 운영체제는 윈도우가 무효영역을 가지고 있으면 이 윈도우에게 WM_PAlNT 메시지 를 보내 다시 그리게 한다.

 

직접 복구하지 않는 대신 철저하게 신호를 보내 스스로 그리기 를 할 수 있도록 도움을 준다.

 

● BOOL InvalidateRect(HWND hWnd, const RECT * lpRect, BOOL bErase)

프로그램 의 내부에서 윈도우의 모습을 변경시켰을 때 변경된 부분을 다시 그리도록 강제로 무효화해야하며 이때사용하는 함수가 바로 InvalidateRect 이다. 이 함수는 윈도우의 작업영역을 무효화하여 운영체제로 하여금 WM_PAINT 메시지를 해당 윈도우로 보내도록 한다

 

● WM_KEYDOWN

WM KEYDOWN 메시지 는 키보드를 누를 때마다 윈도우로 전달되는데 문자가 아닌 모든 키에 대 해서도 발생한다 단, Alt키와 윈도우 키, 한영 전환 키 등의 특수 키 몇 가지는 제외된다. 이 때 wParam으로는 문자 코드가 아닌 가상 키코드라는 것이전달된다 가상 키코드(Virtual Key Code)란 시 스템 에 장착된 키보드의 종류에 상관없이 키를 입력받기 위해 만들어 진 범용적인 코드값이 며 다음과 같이 정의 되어 있다.

 

 

● TranslateMessage

TranslateMessage 함수는 전달된 메시지가 WM_KEYDOWN인지와 눌러진 키가 문자키인지 검사해 보고 조건이 맞을 경우 WM_CHAR 메시지 를 추가로 발생시킨다. 물론 문자 업력이 아닐 경우는 아무일도 하지 않으며 이 메시지는 DispatchMessage 함수에 의해 WndProc으로 보내진다. 만약 메시지 루프에서 TranslateMessage 함수를 빼 버리변 WM_CHAR 메시지는 절대로 WndProc으로 전달되지 않을것이다.

 

메시지 루프의 TranslateMessage 함수는 오로지 키보드로부터 문자키 입력 메시지인 WM_CHAR를 만들어 내기 위해 존재한다.

만약 WM_CHAR메시지를 전혀 받을 필요가 없는 프로그램이라면 TranslateMessage 를 빼도 된다.

 

● Mouse

여기서 마우스라고 함은 진짜 쥐 새 끼 처 럼 생 긴 마우스는 물론이 고 노트북의 터치패드, 트랙볼과 출판용 타블릿 등을 모두 포함하는 명칭이다.

키보드 입력 처리를 메시지 로 하는 것과 마찬가지 로 마우스 압 력 처 리 도 메 시지를 받아 처리 한다. 마우스 입력 에 관한 메시지 는 다읍과 같은 종
류가있다.

 

마우스 버 튼의 누름 메시지 외에 마우스가 이동할 때마다 전달되는 WM MOUSEMOVE 메시지가 있다. 이 메시지 도 다른 마우스 메시지와 마찬가지 로 lParam에 마우스 커서의 위치가 전달되며wParam에 조합카 상태가 전달된다. 또한 휠 마우스가 등장함으로써 WM MOUSEWHEEL이라는 메시지가 추가되었다.

 

● Mouse 메시지의 wparam / lparam

마우스 메시지는 IParam의 상위 워드에 마우스 버튼이 눌러진 y좌표, 하위 워드에 x좌표를 가지며 좌표값을 검출해 내기 위해 HIWORD, LOWORD 등의 매 크로 함수를 사용한다. 즉 마우스 메시지가 발생한 위치 의 좌표는 (LOWORD(lParam), HIWORD(lParam))이 된다

 

메시지의 추가 정보로 전달되는 wParam, lParam은 둘 다 32비트 크기를 가지므로 총 64비 트의 정보를 전달할 수 있다.

 

단, 좌표값은 당연히 양수지만 읍수가 되 는 특별 한 경 우도 있음을 주의해야 한다.

 

wParam에는 마우스 버튼의 상태와 키보드 조합 키 (Shift, Ctrl)의 상태 가 전달된다. 조합키 상태는 다음 값들과 비 트 연산을 해보면 알 수 있다. 이 값을 참조하면 쉬프트 클릭, 좌우 동시 누름 등의 조건을 검출할수 있다.

 

 

 

 

 

 

● Mouse 더블클릭

더 블클릭이란 짧은 시간 안에 마우스 버튼을 두 번 빠르게 누르는 동작인데 프로그램 실행, 확정적인
선택 등에 많이 사용된다. 왼쪽 마우스 더블클릭 메시지는 WM_LBUTTONDBLCLK 이다.

 

- 사용전 사전준비

 

WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAWI CS_VREDRAWI CS_DBLCLKS;        // 스타일에 등록한다
ReglsterClass( & WndClass)

 

// 그리고 Proc함수에 추가하여 사용함 된다.

case WM LBUTTONDBLCLK:
InvalidateRect(hWnd, NULL, TRUE);
return 0;

 

● 타이머

대표 적으로 타이머 메시지인 WM_TIMER 이 메시지는 한 번 지정해 놓기만 하면 일정한 시간 간격을 두고 연속적으로 계속 발생한다. 주기적으로 같은 동작을 반복해야 한다거나 여러 번 나누어 해야 할 일이 있을 때 이 메시지 를 이용한다.

 

- UINT SetTimer(HWND hWnd,UINT nIDEvent, Uint uElapse, TIMERPROC lpTimerFunc);

1. 단위는 1/1000초이다

2. 타이머의 최대 해상도는95/98에서는 0.055초이며 NT/2000에서는 0.01초에 불과하다 (1초에 100회 /98에서는 18회)

 

- BOOL KiIITimer( HWND hWnd, UINT ulDEvent);

1. 설치된 타이머를 제거하는 것이며

 

-현재 시간을 구하기

SYSTEMTIME구조체와 GetLocalTime함수를 이용

 

 

● Send Message

LRESULT SendMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

메시지는 사용자의 동작이나 시스템상황에 의해 발생하는 것이 원칙이지만 강제로 메시지가 발생한 것처럼 만들어야 할 때는 이 함수를 사용하여 hWnd 윈도우로 Msg 메시지 를 보내면 된다. 그러면 hWnd는 Msg 메시지가 발생한 것으로 인식하고 필요한 처리 를 하게 될 것이다.

 

● 콜백함수

VOID CALLBACK TimerProc(HWND hWnd, UINT umsg, UINT idEvent,DWORD dwTime);

아무튼 중요한 사실은 이런 원형을 가지는 함수를 만든 후 SetTimer 함수의 네 번째 인수에 이 함수명을 전달하면 지정한 시간 간격으로 이 함수가 호출된다는 점이다.

 

1. API 함수들은 운영체제가 제공하며 프로그램에서는 이 함수들을 호출하여 운영체제의 서비스를 받는 다.

2. 콜백함수는 응용 프로그램이 제공하며 운영체제가 필요할때 호출하는 함수이다

3. 호출되는 방향이 거꾸로 되었기 때문에 콜백이라 부르는 것이다.

4. 콜백함수의 예는 메시지 처리함수인 WndProc이다 이 함수는 메시지가 발생할 때마다 윈도우즈가 호출하며 응용프로그램 내부에 있지만 응용프

    로그램에서 직접 이 함수를 호출하지 않는다 오직 운영체제만이 이 함수를 호출한다.

 

타이머의 경우 콜백함수를 사용하는 것과 WM TIMER 메시지 를 받는 것은 사실상 거의 통일한 기법이라고 할 수 있으며 상황에 따라 편리한 방법을 사용하면 된다. 차이점이라면 WM TIMER 메시지는 다른 메시 지 가 있을 경우 실행 순서에 밀려 늦게 호출되는 경우가 있지만 콜백함수를 사용하
면 절활한꺼낸에 후출된다는결,0 1 다 그래서 정확도를 요하는 작업은 타이머 메시지보다는 콜백함수를 사용하는 것이 더 좋다고 되어 있다. 하지만 Win32 환경에서 는 사실상 별 차이가 없다.

 

-일회용 타이머

Sleep() : 이 함수는 도스의 delay와 기능상 동일하며 지정한 동안 프로그램의 실행을 잠시 정지시킨다

Sleep 함수는 지정한 시간동안 프로그램을 완전히 정지시켜 버리므로 대기하는 동안에는 다른 일체의 작업을 할 수 없다. 문자열을 표시하는 3초 동안은 윈도우를 이동할 수도 없고 키 입력에도 반응하지 않는다. 심지어 WMPAINT 메시지도 처리하지 못하기 때문에 3초 내에 다른 윈도우가 이 윈도우를 가리면 문자열을 다시 그리지도 못한다.

 

● 생성 및 파괴

WM_CREATE와 WM_DESTROY 두 가지가 있다. WM_CREATE 메시지 는 윈도우가 생성될 때 보내지므로 각종 초기화를 하기에 적합한 장소이며
반대로 윈도우가 파괴될 때 보내지는 WM_DESTROY 메시지는 종료처리를 하기에 적합하다 두 메시지는 윈도우의 일생을 통틀어 딱 한 번씩만 전달되는 특성이 있어 일회적인 작업인 초기, 종료 처리에 사용할 수 있다.

 

WM_DESTROY에서 주의할 것은 메 인 윈도우의 경우 반드시 PostQuitMessage 함수를 호출해야 한다는 점이다.

메인 윈도우는 응용 프로그램이 처음 만드는 윈도우인데 자신이 파괴될 때 응용 프로그램을 종료해야 하는 막중한 임무가 부여되어 있다. PostQuitMessage 함수는 메시지 큐에 WM_QUIT를 넣음으로써 WinMain에 있는 메시지 루프를 종료시카고 WinMain 함수 자체를 종료하여 운영체제로 복귀 시키는 역할을 한다.

 

● 작업영역

윈도우는 작업영역(Client Area)과 비작업영역이(Non Client Area) 두 부분으로 구성되어 있다

작업영역 이란 쉽게 말해서 윈도우 중앙의 흰 부분을 말하며 비작업영역이란 그 외의 영역을 말한다. 비작업영역 에 속하는 부분은 일단 타이틀 바와 경계선이 있고 메뉴가 있을 경우 메뉴도 비작업영역에 속한다. 작업/비 작업영역의 구분은 윈도우를 이해하는데 중요한 비 중을 차지하는데 왜냐하면 프로그래밍 대상이 되 는 것은 작업영역 에 한정되 기 때문이다.

 

- BOOL GetClientRect(HWND hWnd, LPRECT lpRect); ※ 사용할수 있는 진정한 영역

원하는 위치에 정확하게 출력 하려면 윈도우가 차지 하고 있는 영역의 좌표를 조사해 야 하는 것 이 아니라 작업 영역의 좌표를 조사해야 한다.

이를 위해 사용하는것이 바로 이함수다.

 

● WM_SIZE

문자열을 계 속 작업영역 중앙에 두고 싶으면 윈도우의 크기가 변경될 때마다 다시 춤력해야 하는데 이때 사용되는 메시지가 WM_SIZE이다. 이 메시지는 윈도우의 크기가 변경될 때 전달되 는데 lParam의 하위 워드에는 변경된 후의 윈도우 폭이 상위 워드에는 높이가 전달되며 wParam에는 이 메시지가 발생한 이유를 나타내는 플래그가 전달된다.

 

 

 

다음과 같이 사용될 수 있다.

case WM SIZE:
    rt.right=LOWORD(IParam);
    rt.bottom=HIWORD(IParam);
    InvalidateRect(hWnd, NULL, TRUE);
return 0;

 

 

 

● WM_MOVE

이 메시지는 윈도우의 위치가 변경될때마다 보내지는데 lParam의 하위 워드에 윈도우의 새 X좌표 상위 워드에 윈도우의 새 Y 좌표가 전달된다.

그러나 현실적으로 이 메시지는 잘 사용되지 않는다. 왜냐하면 위치 는 크기와 달리 응용 프로그램에 별다른 영향을 주지 않기 때문이다.

 

 

 

'프로그래밍 > 공부' 카테고리의 다른 글

DX 기본수학 (2)  (0) 2013.06.19
Dx 기본 수학 (1)  (0) 2013.06.19
API 3장  (0) 2013.04.16
API 2장  (0) 2013.04.16
AIP 1장  (0) 2013.04.16
Posted by 피씨컴

API 3장

프로그래밍/공부 2013. 4. 16. 05:51

● DC의 필요성

DC(Device Context)란 출력에 필요한 모든 정보를 가지는 데이터 구조체이며 GDI 모률에 의해 관리된다. 문자열의 모양을 지정하는 폰트 선의 색상

과 굵기 채움 무늬와 색상, 그리기 모드 등등이 모두 출력에 필요한 정보들이다.

 

● 문자열 출력

TextOut(hdc, 100, 100, TEXT("Beautiful Korea ",15);

 

● WM_PAINT 메시지

1. 운영체제가 개별 윈도우의 화변을 보관 및 복구해 주지 않는다.

2. 멀티 태 스킹 시스템인 윈도우즈에서는 여러 개의 윈도우가 겹칠 수 있으므로 한 번 출력해 놓은 문자열이 언제까지고 그대로 그 자리에 있는다는

    보장이없다

3. 윈도우즈는 가려졌던 윈도우의 화면을 보관 및 복구하는 책임을 지지 않는다.

4. 화면이 지워지는 그 시점이 바로 WM_PAINT 메시지이다.

 

운영체제는 개별 윈도우의 화면을 보관해 주지는 않지만 대신 윈도우의  일부가 지워졌다는 사실을 프로그램으로 즉각 알리며 그 방법은 WM_PAINT 메시지 를 보내주는 것이다 WM_PAINT 메시지는 “너의 작업영역이 일부 지워 졌으니 까 빨리 다시 그려라”는 뜻이다.

 

● DC를 얻는 방법

HDC GetDC(HWND hWnd);
int ReleaseDC(HWND hWnd,HDC hDC);

 

DC는 주로 하나의 윈도우와 연관되는 출력 정보를 가진다 그래서 인수로 어떤 윈도우에 대한DC가 필요한가를 밝혀야 한다. GetDC는 hWnd가 가리키 는 윈도우에 적당한 DC를 만들어 그 핸들을 리턴한다.

 

DC를 얻는 두 번째 방법은 WM PAINT 메시지 루틴에서만 사용할 수 있다. WMPAINT 메시지
처리 루틴에서는 DC 핸들을 GetDC로 얻지 않고 BeginPaint 함수로 얻으며 핸들을 해제할 때는
EndPaint 함수를 사용한다.

 

HDC BeginPaint(HWND hwnd, LPPAINTSTRUCT IpPaint);
BOOL EndPaint(HWND hWnd,CONST PAINTSTRUCT *lpPaint);

 

● BOOL TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR IpString , int cbString);

문자열을 출력하는 TextOut 함수이며 콘솔의 printf에 해당하는 함수이다.

 

-SetTextAlign(HDC hdc, UNIT fMode) : 문자열의 정렬 방법을 변경하는 함수

 

디폴트 정렬 상태 는 TA_TOP I TA_LEFT로 되어 있으며 지정 한 좌표를 화상단으로 하여 문자열이 출력된다 물론 정렬 상태를 변경하면 지정한 좌표를 문자열의 어 느 지점으로 사용할 것인가를 변경할 수 있다.

 

 

 

 

● int DrawText( HDC hDC, LPCTSTR lpString, int nCount, LPRECT lpRect, UINT uFormat);

이 함수는 사각영역을 정의하여 영역 안에 문자열을 출력할 수 있으며 여러 가지 포맷을 설정하는 기능이 있다. 윈도우즈에서 사각영역 을 정의할 때는 RECT 구조체를 사용한다.

 

 

 

● 그래픽 출력 

SetPixel : 화면에 점을 출력하는데(nXPos, nYPos) 좌표에 clrref 색상으로 점을 출력 한다

MoveToEx / LineTo : 선을 그을 때 같이 사용해야 하는 함수

LineTo : CP에서부터 지정한 좌표까지 선을 그으며 CP를끝점으로 이동시킨다. 연속적으로 호출하면 계속 이어지는 선을 그을 수 있다.

MoveToEx : CP를 지정한 좌표 (x,y)로 이동시키며 이동 전의 CP 좌표를 lpPoint에 대입하는데 이 전 CP값이 필요치 않은 경우 lpPoint에 NULL을 전달하면 된다.

Rectangle : 지정한 두 점 (Left, Top)과 (Right, Bottom)을 대각선으로 하는 사각형을 그리며 사각형 내부를채우기도 한다

Ellipse : 함수는 지정한 사각형에 내접하는 타원을 그린다.

 

● int MessageBox(HWND hWnd, LPCTSTR IpText, LPCTSTR IpCaption, UINT uType);

메시지 박스는 조그만 별도의 윈도우를 열어서 사용자에게 정보를 전달하거나 질문을 하는 장치 이며 MessageBox 함수 호출 한 번으로 비교적 간단하게 만들 수 있다

 

 

 

if (MessageBox(hWnd, TEXT(" 게 임 을 계 속 하겠습 니 까"), TEXT(" 질 문"), MB_ YESNO)==IDYES)

{
// 게임 계속 처리

} else

 {
// 게임 중지

}

 

전달사항을 단순히 전달하는 용도 외에 사용자에게 질문을 하고 대답을 입력받는 용도로도 사용할 수 있다. 이 때 는 메시지 박스를 호출한 후 사용자

가 어떤 버튼을 눌렀는지를 살펴보면 되는데MessageBox 함수는 리턴값으로 사용자가 누른 버 튼값을 돌려준다.

 

 

 

● BOOL MessageBeep(UINT uType);

문자열이나 그래픽, 메시지 박스처럼 눈에 보이는 출력도 있지만 비 프음을 내 는 들리는 종류의 출
력도 있다 스피커를 통해 간단한 비프음을 출력할 때 는 MessageBeep 함수를 사용한다. 

 

 

'프로그래밍 > 공부' 카테고리의 다른 글

Dx 기본 수학 (1)  (0) 2013.06.19
API 4장  (1) 2013.04.17
API 2장  (0) 2013.04.16
AIP 1장  (0) 2013.04.16
정리정리  (0) 2013.03.20
Posted by 피씨컴

API 2장

프로그래밍/공부 2013. 4. 16. 03:37

● First 예제

 

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass="First";

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
		  ,LPSTR lpszCmdParam,int nCmdShow)
{
	HWND hWnd;
	MSG Message;
	WNDCLASS WndClass;
	g_hInst=hInstance;
	
	WndClass.cbClsExtra=0;
	WndClass.cbWndExtra=0;
	WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
	WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	WndClass.hInstance=hInstance;
	WndClass.lpfnWndProc=(WNDPROC)WndProc;
	WndClass.lpszClassName=lpszClass;
	WndClass.lpszMenuName=NULL;
	WndClass.style=CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&WndClass);

	hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
		  CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
		  NULL,(HMENU)NULL,hInstance,NULL);
	ShowWindow(hWnd,nCmdShow);
	
	while(GetMessage(&Message,0,0,0)) {
		TranslateMessage(&Message);
		DispatchMessage(&Message);
	}
	return Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
	switch(iMessage) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

아무런 기능도 없으며 단지 윈도우를 하나 만들었을 뿐이다. 그러나 간단해 보여도 완전히 온전한 하나의 윈도우이므로 표준 윈도우가 가진 모든

기능을 다 발휘할 수 있다.

 

 

● First 예제 분석

 

- 헤더파일

도스에서는 사용하는 함수의 종류에 따라 여러 개의 헤더 파일을 포함하지만 윈도우즈에서는 하나의 헤더 파일에 모든 API 함수들의
원형과 사용하는 상수들이 죄다 정의되어 있기 때문에 windows.h만 포함하면 된다.

 

- 시작점

다음으로 차이나는 점은 프로그램의 시작점인 엔트리 포인트(EntIy Point)가 main이 아니라 WinMain이라는 점이다. 윈도우즈 프로그램의 시작점은 main이 아닌 WinMain이며 모든 윈도우즈 프로그램은 WinMain에서부터 실행을 시작한다.

※ APIENTRY 지정자는 윈도우즈의 표준 호출 규약인 _stdcall 을 사용한다는 뜻

 

1. hlnstance

프로그램의 인스턴스 핸들이다.

2. hPrevlnstance

바로 앞에 실행된 현재 프로그램의 인스턴스 핸들이다. 없을 경우는 NULL이 되며 Win32에서는 항상 NULL이다. 16비트와의 호환성을 위해서만 존재하는 인수이므로 신경쓰지 않아도 된다 역사가 오래되다 보니 어찔 수 없이 샘기는 일종의 찌꺼기이다.

 

3. IpszCmdParam

영령행으로 입럭된 프로그램 인수이다. 도스 의 argv인수에 해당하며 보통 실행
직후에 열 파일의 경로가 전달된다


4. nCmdShow

프로그램이 실행될 형태이며 최소화,보통 모앙 등이 전달된다.

 

5. Instance란?

인스턴스(instance)라는 말은 실행중인 프로그램 하나를 칭하는 용어이다. 윈도우즈는 여러 개의 프로그램이 동시에 실행되는 멀티 태스킹 시스템일 뿐만 아니라 하나의 프로그램 이 여러 번 실행될 수도 있다. 이때 실행되고 있는 각각의 프로그램을 프 로그램 인스턴스라고 하며 간단히 줄여서 인스턴스라고 한다.

 

- 메시지 처리 함수

WndProc은 사용자와 시 스템 이 보내오는 메시지 를 처리하는 아주 중요한 일을 한다 WinMain은 메인 윈도우를 만들고 화면에 윈도우를 표시하기만 할 뿐이며 대부분의 일은 WndProc 에서 이루어진다. WinMain은 프로그램을 초기화하고 시작시키기만 하므로 모양이 대체 로 일정한데
비해 WndProc은 프로그램의 실질적이고도 고유한 처리를 하는 곳이므로 프로그램 에 따라 천차만별 로 달라진다.

 

- 윈도우 클래스

윈도우를 만들려면 윈도우클래스를 먼저 등록한 후 CreateWindow 함수를 호출해야 한다. 윈도우 클 래 스는 만들어질 윈도우의 여러 가지 특성을 정의하는 구조체이며 모든 윈도우는 윈도우 클래스의 정보를 기반으로 하여 만들어진다.

윈도우 클래스는 windows.h에 다음과 같이 정의되어 있는 구조체이다.

 

typedef struct tagWNDCLASS

{
UINT     style;
WNDPROC     IpfnWndProc;
int    cbClsExtra;
int    cbWndExtra;
HINSTANCE    hlnstance;
HICON    hlcon;
HCURSOR    hCursor;

HBRUSH    hbrBackground;
LPCSTR     IpszMenuName;
LPCSTR    IpszClassName;
} WNDCLASS;

 

1. style    :    윈도우의 스타일을 정의한다. 즉 윈도우가 어떤 형태를 가질 것인가를 지정하는 멤버이다.

2.  IpfnWndProc :이 멤버는 윈도우의 메시지 처리 함수를 지정한다. 메시지가 발생할 때마다 이 멤버가 지정하는 함수가 호출되며 이 함수가 모

든 메시지를 처리한다.    

3. cbCIsExtra, cbWndExtra : 일종의 예약 영역이다. 윈도우즈가 내부적으로 사용하며 아주 특수한 목적에 사용되는 여분의 공간이다. 예약 영역

    을 사용하지 않을 경우는 0으로 지정한다,

4. hInstance : 이 윈도우 클래스를 등록하는 프로그램의 번호.  운영체제는 이 윈도우 클래스를 누가 등록했는지 기억해 두었다가 프로그램이 종

  료될 때 등록을취소한다

5. hIcon, hCursor : 윈도우가 사용할 마우스 커서 와 아이콘을 지 정 한다.

6. hbrBackground : 윈도우의 배경 색상을 지정한다. 좀 더 정확하게 표현하면 윈도우의 배경 색상을 채색할 브러시를 지정하는 멤버이다.

7. lpszMenuName: 이 프로그램이 사용할 메뉴를 지정한다.

8. lpszClassName : 윈도우 클래스의 이 름을 문자열로 정의한다. 여기서 지정한 이 름은 CreateWindow 함수에 전달되며 CreateWindow 함수

                             는 윈도우 클래스에서 정의한 특성값을 참조하여 윈도우를 만든다.

9 ATOM RegisterClass : RegisterClass 함수의 인수로 WNDCLASS 구조체의 번지 를 전달한다. 이런 이런 특성을 가진 윈도우를 앞으로 사용

                                   하겠다는 등록 과정이며 운영체제는 이 윈도우 클래스의 특성을 잘 기억해 놓는다.

 

- 윈도우 생성

윈도우 클래스를 등록한 후에는 이 윈도우 클래 스를 기본으로 실제 윈도우를 생성한다. 윈도우를 생성할 때는 CreateWindow 함수를 사용한다.

HWND CreateWindow(lpszClassName, IpszWindowName, dw5tyle, x, y, nWidth, nHeight, hwndParent, hmenu, hinst, Ipvparam);

 

1. IpszClassName : 생성하고자 하는 윈도우의 클래스를 지정하는 문자열이다.

2. IpszWindowName : 윈도우의 타이틀 바에 나타날 문자열이다. 여기서 지정한 문자열이 윈도우의 타이 툴 바에 나타난다.

3. dwStyle : 만들고자 하는 윈도우의 형 태 를 지정하는 인수이다. 일종의 비 트 필드값이며 거의 수십 개를 헤아리 는 매 크로 상수들이 정의되

                 어 있고 이 상수틀을 OR연산자로 연결하여 윈도우의 다양한 형태를 지정한다.

4. X, Y, nWidth, nHeight : 인수의 이 름이 의미하듯이 윈도우의 크기와 위치 를 지정하며 픽셀 단위를 사용한다.

5. hWndParent: 부모 윈도우가 있을 경우 부모 윈도우의 핸들을 지정한다.

6. hmenu : 윈도우에서 사용할 메뉴의 핸들을 지정한다.

7. hinst : 윈도우를 만드는 주체, 즉 프로그램의 핸들을 지정한다.

8. IpvParam : CREATESTRUCT라는 구조체의 번지이며 여 러 개의 윈도우를 만들 때 각 윈도우에 고유의 파라미터를 전달하는 특수한 목적에 사

  용된다 보통은 M凡L값을 사용하며 잘 사용되지 않으므로 일단은무시하자.

9 . BOOL ShowWindow(hWnd, nCmdShow)

메모리에 만들어진 윈도우를 화면으로 보이게 하려면 다음 함수를 사용해야한다.

 

SW HIDE                   윈도부를 숨긴다.
SW MINIMIZE            윈도우를 최소화하고 활성화시키지 않는다.
SW RESTORE            윈도우를 활성화시킨다.
SW SHOW                 윈도우를 활성화하여 보여준다
SW SHOWNORMAL    윈도우를 활성화하여 보여준다.

- 윈도우를 만드는 과정

 

 

- 메시지 루프

윈도우즈 프로그램에서 메시지 를 처리하는 부분을 메시지 루프(Message Loop)라고 하며 보통 WinMain 함수의 끝에 다음과 같은 형식으로 존재한다, 메인 윈도우를 만든 직후 WinMain은 메시지 루프를 실행한다.

 

while (GetMessage(&Message,NULL,0,0)) {
TranslateMessage( &Message);
DispatchMessage( &Message);

}

 

1. BOOL GetMessage(LPMSG IpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

메시지 큐(Message Queue)는 시스템이나 사용자로 부터 발생된 메시지가 잠시 대기하는 일종의 메시지 임시 저장 영역이다. 읽어들인 메

시지는 첫 번째인수가 지정하는 MSG 구조체에 저장된다. 이 함수는 읽어들인 메시지가 프로그램을 종료하라는 WM_QUIT일 경우 FALSE를 리턴하며 그 외의 메시지이변 TRUE를 리턴한다. 따라서 WM_QUIT 메시지가 읽혀질 때까지, 즉 프로그램이 종료될 때까지 전체 while 루프가 계속 반복된다. 나머지 세 개 의 인수는 읽어들일 메시지의 범위를 지정하는데 잘 사용되지 않으므로 일단 무시하기로 한다

 

2. BOOL TranslateMessage(CONST MSG *lpMsg);

이 함수는 키보드 입력 메시지를 가공하여 프로그램에서 쉽게 쓸 수 있도록 한다. 윈도우즈는 키보드의 어떤 키가 눌러지거나 떨어졌을 때 키보드 메시지를 발생시키는데 TranslateMessage 함수는 키보드의 눌림 (WM_KEYDOWN) 메시지가 발생할 때 문자가 입력되었다는 메시지(WM_CHAR)를 만드는 역할을 한다.

 

3. LONG DispatchMessage(CONST MSG *Ipmsg);

이 함수는 메시지 큐에서 꺼낸 메시지를 윈도우의 메시 지 처리 함수(WndProc)로 전달한다 이 함수에 의해 메시지가 윈도우로 전달되며 프로그램(정확하게 표현하면 윈도우 프로시저)에서는 전달된메시지 를 점검하여 다읍 동작을 결정한다. 이 함수가 메시지 를 전달하면 다시 루프의 선두로 돌아가 다음 메시지를 기다린다.

 

메시지 루프의 세 함수는 공통적으로 MSG라는 구조체를 사용하는데 이 구조체는 메시지에 대한 정보를 정의한다.

 

typedef struct tagMSG

{
HWND     hwnd;
UINT         message;
WPARAM    wParam;
LPARAM    IParam;
DWORD    time;
POINT    pt;
} MSG;

1. hwnd : 메시지를 받을 윈도우 핸틀이다

2. message : 어떤 종류의 메시지인가를 Lf 타낸다. 가장 중요한 값이다.

3. wParam : 전달된 메시지에 대한 부가적인 정보를 가진다. 어떤 의미를 가지는가는 메시지열로 다르다 32 비트 값이다

4. IParam : 전달된 메시지에 대한 부가적인 정보를 가진다 어떤 의미를 가지는가는 메시지별로 다르다 32 비트 값이다

5. time : 메 시지가 발생한 시간이 다

6. pt : 메시지가 발생했을 때의 마우스 위치이다.

 

message 멤버 를 읽음으로써 메시지의 종류를 파악하며 message값에 따라 프로그램 의 반응이 달라진다. wParam,lParam은 메시지에 대한 부가적인 정보를 가지되 메시지 별로 의미가 다르다. GetMessage 함수는 원은 메시지 를 MSG형의 구조체에 대입하며 이 구조체는 DispatchMessage 함수에 의해 응용 프로그램의 메시지 처리 함수(WndProc)로 전달된다.

 

WM QUIT                                :프로그램을 끝낼 때 발생하는 메시지이다
WM LBUTTONDOWN                :마우스의 좌측 버튼을 누를 경우 발생한다
WM KEYDOWN                        : 키보드의 키를 눌렀다

WM_CHAR                              : 키보드로부터 문자가 입력될 때 발생한다.

WM_PAINT                             : 화면을 다시 그려야 할 필요가 있을때 발생한다.
WM CREATE                          : 윈도우가 처음 만들어질 때 발생한다.

WM DESTROY                        : 윈도우가 메모리에서 파괴될 때 발샘한다.

 

메시지 루프가 종료되면 프로그램은 마지막으로 Message.wParam을 리턴하고 종료한다. 이 값은 WM_QUIT 메시지로부터 전달된 탈출 코드(exit code)이며 이 프로그램을 실행시킨 운영체제로 리턴된다.

 

 

- 윈도우 프로시저

윈도우 프로시저(Window Procedure)라는 뜻이지만 통상 읽을 때는 콩글리쉬로 “윈드프록”이라고 읽는다. WndProc은 WinMain에서 호출하는

것이 아니라 운영체제에 의해 호출된다. WinMain내의 메시지 루프는 메시지를 메시지 처리 함수로 보내기만 할 뿐이며 WndProc은 메시지가 입

력되면 운영체제에 의해 호출되 어 메시지를 처리한다.

 

메시지를 처리하는 WndProc의 구조는 대체로 다음과 같은 형태를 가진다. 다양한 종류의 메시지가 전달될 수 있는데 전달된 메시지의 종류에 따

라 다중 분기하여 운영체제로부터 전달된 신호에 반응하는 형식이다.

 

switch (iMessage) {
case Msg1:
처리 1;
return 0;
case Msg2:
처리 2'
return 0;
case Msg3:
처리 3;
return 0;
default:
return DefWindowProc( ... );

}

 

제일 끝에 있는 DefWindowProc 함수는 WndProc 에서 처리하지 않은 나머지 메시지에 관한 처리를 한다 예를 들어 시스템 메뉴를 더블클릭하면

프로그램이 종료되는데 이런 처리는 별도로 하지 않아도 DefWindowProc 함수에서 알아서 한다. 그래서 윈도우의 이동이나 크기 변경 따위의 처

리는 프로그램이 직접 할 필요없이 DefWindowProc으로 넘기기만 하면 된다

 

 

● 메시지 루프와 메시지 처리 함수의 전체 적 인 순서도

 

 

● 배경색 바꾸기

WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

 

여기서 사용된 GetStockObject함수는 윈도우즈가 기본적으로 제공하는 브러시, 펜 등의 핸들을 구 하는 함수인 데 이 함수의 인수로 WHITE_BRUSH를 지정했기 때문에 배경색을 칠하는 데 흰색 브러시가 사용되었다. 이 값을 BLACK BRUSH로 변경하면 검정색이 배경색으로 사

용되며LTGAY BRUSH로 변경 하면 열은 회색 배경이 만들어진다.

 

 

● 커서 바꾸기

WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

 

hCursor 멤버는 윈도우가 기본적으로 사용할 커서를 지정하며 LoadCursor 함수는 커서를 읽어 오는함수이다.

 

● 윈도우 타이틀 바꾸기

CreateWindow 함수의두 번째 인수로 지정한 lpszClass 문자열이며 이는 또한 윈도우 클래스의 이름이기도 하다. 타이틀 바에 나타나는 윈도우의 이

름을 변경하려면 CreateWindow 함수의 두 번째 인수를 원하는 문자열로 변경하면 된다.

 

hWnd=CreateWindow(lpszClass, TEXT("My First program"),WS_OVERLAPPEDWINDOW, CW_USEOEFAULT,CW_USEDEFAULT,

CW_USEDEFAULT,CW USEOEFAULT,NULL,(HMENU)NULL,hlnstance,NULL);

 

● 윈도우 스타일

CreateWindow함수의 세 번째 인수 dwStyle은 윈도우의 모양과 동작 방식을 결정하는 여러 가지 속성을 지정한다. 여러 가지 스타일값을 가지는 32

비트 정수값이며 이 값을 변경함에 따라 다양한 모양의 윈도우를 만들 수 있다. 일단 dwStyle에 사용될 수 있는 값들을 보자. 이 값들을 OR연산자로

연결하여 여러 가지 속성을 한꺼번에 지정한다, 

 

WS OVERLAPPEDWINDOW는 다음과 같이 정의되어 있다

 #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED I WS_CAPTION I WS_SYSMENU | WS_THICKFRAME I WS_MINIMIZEBOX I WS_MAXIMIZEBOX)

 

 

 

 

'프로그래밍 > 공부' 카테고리의 다른 글

API 4장  (1) 2013.04.17
API 3장  (0) 2013.04.16
AIP 1장  (0) 2013.04.16
정리정리  (0) 2013.03.20
3/8  (0) 2013.03.11
Posted by 피씨컴

AIP 1장

프로그래밍/공부 2013. 4. 16. 01:19

● API란?

Application Programming Interface의 약저이며 우리말로 풀어본다면 운영체제가 응용 프로그램을 위해 제공하는 함수의 집합이라고 정의할 수 있다.

 

● 특징 & 장점

1. 그래픽 기반(GUI)의 운영체제이다.

2. 멀티 태스킹이 가능하다 (GetMessage 덕분)

3. 메시지 구동 시스템이다 (이벤트 드리븐)

4. 장치에 독립적이다.

5. 일관성이 있다

6. 리소스가 분리되어 있다. (코드를 제외한 모든것이 리소스이다.)

 

 

● 여러가지 개발 방법

1. SDK (software Development Kit)

        윈도우즈를 만든 마이크로소프트사에서 제공하는 윈도우즈용 프로그램 개발 킷이다. 운영체제가 제공하는 함수(API 함수)들을 사용하여 프로

  그램을 작성하며 가장 원론적이고 가장 먼저 발표된 개발 방법이다 운영체제가 직접 제공하는 함수를 사용하므로 섬세한 처리를 할 수 있으며

  아주 막강한 기능의 프로그램을 작성할 수 있을 뿐만 아니라 프로그램의 속도 나 크기에도 아주 유리하다.

 

2. 클래스 라이브러리

 복잡하고 양이 많은 API 함수들을 좀 더 쉽고 빠르게 사용하기 위해 클래스로 잘 포장하여 객체위주로 프로그램을 작성하는 방법이다. 윈도우즈

 프로그래밍에 필요한 클래스들을 미리 작성해 놓고 객체를 조립 하여 프로그램을 만들어 나간다. 클래스가 워낙 잘 설계되어 있기 때문에 사용하

 기 무척 쉬울 뿐만 아니라 기능 또한 아주 막강하다. 윈도우즈용 클래스 라이브러리에는 마이크로소프트사의 MFC와 볼랜드사의 OWL이 대표적

 이다 MFC는 비 주얼 C뷰에 포함되어 있으며 OWL은 볼랜드 C뷰 에 포함되어 있다. 현재는 MFC를 더 많이 사용하며 OWL은 거의 사용되지 않

 는다.

 

3. 비주얼 툴

비 주얼 툴은 손으로 일일이 코드를 작성하지 않고 마우스로 마치 그림을 그리듯 화면을 디자인하며 꼭 필요한 곳에만 간단한 코드를 작성하는 아주 진보된 개발툴이다. 그래서 배우기도 쉽고 사용하기도 쉬울뿐만 아니라 기능도 타 개발방법에 비해 심하게 떨어지지 않는다 현재까지 발표된 비주얼 개발툴에는 비 주얼 베이직과 델파이 정도가 있으며 데이터 베이 스 전용의 몇몇 툴이 있다.

 

● API를 알아야 하는 이유

1. 운영체제를 이해하기 위해

2. 어차피 알아야 하므로

3. 자유를 얻기 위해

4. 가장 자연스러운 학습과정이므로

 

● 변수 명명법

cb         count of bytes         바이트 수

dw        double word            부호없는 long형 정수

h          handle                     윈도우,비트맵,파일 등의 핸들

sz        Null Terminated          NULL 종료 문자열

ch        Character                  문자형

a          Array                         배열

w         word                         부호없는 정수

i            Integer                     정수형

p,lp        long Pointer             포인터형

b           Bool                        논리형

 

이를 헝가리식 명명법.

 

● 사용자 정의 데이터형

BYTE            unsigned char형

CHAR            char 형

WORD            unsigned short형

DWORD          unsigned long형

LONG             long과 동일하다

BOOL             정수형이며, TRUE, FALSE중 한값을 가진다.

 

 

 

● 핸들에 대한 이해

핸들(handle)이란 구체적인 어떤 대상에 붙여진 번호이며 문법적으로는 32비트(또는 64비트)의 정수 값이다. 윈도우즈에서는 여러 가
지 종류의 핸들이 사용되고 있다 만들어진 윈도우에는 윈도우 핸들(hWnd)을 붙여 번호로 관리하며 아직은 잘 모르겠지만 DC 에 대해서도 핸들을 사용하고 논리적 펜‘ 브러시에도 핸들을 붙여 관리한다.

 

- 왜이렇게 핸들을 자주 사용하는가?

대상끼리 구분을 위해서는 문자열 보다 정수를 사용하는 것이 속도가 훨씬 더 빠르고 간편하기 때문이다.

 

- 핸들의 특징

1. 핸들은 일단 정수값이며 대부분의 경우 32비트값이다 핸들을 사용하는 목적은 오로지 구분을 위한 것이므로 핸들끼리 중복되지 않아야 하며

    이런 목적으로는 정수형이 가장 적합하다. 정수형은 비교나 대입 연산이 가장 빠른 타입이므로 핸들로 쓰기 에 적합하다.

 

2. 핸들은 운영체제가 발급하며 사용자는 쓰기만 한다. 예를 들어 윈도우를 만들거나 파일을 열면 운영체제는 만들어진 윈도우나 열려진 파일에

    핸들을 붙이고 그 값을 리턴한다. 사용자는 이 핸들을 잘 보관해 두었다가 해당 윈도우나 파일을 다시 참조할 때 사용한다. 사용자가 직접 핸들

     을만드는경우는 없다.

 

3. 같은 종류의 핸들끼리는 절대로 중복된 값을 가지지 않는다. 만약 이렇게 된다면 대상을 구분하는 본래의 목적을 달성할 수 없을 것이다. 물론

   다른 종류의 핸들끼리는 중복된 값을 가질 수도있다.

 

4. 핸들은 정수형이므로 값을 가지겠지만 그 실제값이 무엇인지는 올라도 상관없다. 핸들은 크고 작음의 성질을 가지는 숫자가 아니라 단순한 표

    식일 뿐이다. 핸들형 변수를 만들어 핸들을 대입받아 쓰고 난 후에는 버리면 된다. 마치 malloc한 포인터의 실제 위치가 어디인가 신경쓸 필요

    없이 사용하다가 free로 해제하면 그만인 것과 같다.

 

윈도우즈에서 핸들은 예외없이 접두어 H로 시작되며 핸들값을 저장하기 위해 별도의 데이터형까지 정의해 두고 있다. HWND, HPEN, HBRUSH, HDC 등이 핸들을 담기 위한 데이터형들이며 모두 부호없는 정수 이다.

 

 

● 비트 OR 연산자

윈도우즈 API 함수들도 마찬가지로 작업에 대한 세부 정보(옵션)를 인수로 전달받는다, 그런 데 전달 가능한 옵션이 여러 개 있을 경우 필요한 옵션수만큼 인수를 전달받는 것이 아니라 하나의 인수에 복수 개의 옵션을 묶어 전달하는데 이 때 사용되는 연산자가 비트 OR연산자(|)이다.

비 트 OR 연산자를 사용하면 관심없는 인수는 생략해 버 릴 수 있고 OR 연산은 교환 법칙이 성립하므로 값의 순서에 무관하며 여러 가지 옵션을 묶어서 전달하므로 호출 속도도 빠르다.

 

 

 

 

● 유니코드

유니코드는 16비 트의 단일한 값으로 지구상의 모든 문자를 표현할 수 있는 문자 코드 체계이다.

유니코드를 지원하려변 문자형이나 문자열 에 대해 C언어의 타입을 바로 쓰지 말고 유니코드 설정 에 따라 변경되는 중간 타입 을 사용해야 한

다.C 언어에 익숙한 사람들은 앞으로 문자나 문자열을 표현할 때 다음 타입 들을 쓰도록 하자

 

char                 TCHAR

char*                LPSTR
const char *      LPCTSTR

 

 

TCHAR는 C의 기본 타입 중 하나인 char와 일단 같지만 유니코드로 컴파일 할 때 는 wchar_t 타입
이 된다 wchar_t는 실제로는 unsigned short로 정의되어 있으며 부호없는 16비 트 정수형이다.

 

- 문자열을 다루는 함수

strlen                    lstrlen

strcpy                    lstrcpy

strcat                     lstrcat

strcmp                    lstrcmp

sprintf                    wsprintf

strlen은 char 타업의 문자열 길이만 조사하지만 lstrlen은 TCHAR 타입의 문자열에 대해서도 동작하므로 이식에 훨씬 더 유리하다 문자열 상수도 타엽이 있으므로 겹 따옴표안에 바로 문자열 상수를쓰지 말고 TEXT 매크로로 둘러싸는 것 이 좋다.


TCHAR *str="string";// 이렇게 쓰지 말고
TCHAR *str=TEXT("string"); // TEXT매크로 안에 문자열 상수를 쓴다

 

TEXT 매크로는 유니코드 설정에 따라 문자열 상수의 타입을 변경한다. 유니코드로 컴파일할 때는 각 문자가 16비트의 유니코드 문자가 되며 그렇지 않을 때는 8비트의 안시 (ANSI) 문자가 된다

 

 

'프로그래밍 > 공부' 카테고리의 다른 글

API 3장  (0) 2013.04.16
API 2장  (0) 2013.04.16
정리정리  (0) 2013.03.20
3/8  (0) 2013.03.11
3/7  (0) 2013.03.11
Posted by 피씨컴

degree(도) : 흔하게 쓰는 각도의 단위 오른쪽 위에 작은 동그라미를 그리는 것이 특징

 

 

문제1 : 한 바퀴 돌면 몇도? [ 360도 ]

 

__________________________________________________________________________________________________________________________

π(파이) : 원의 지름을 1이라고 할 때, 원의 둘레의 길이. 약 3.14로 π(파이)로 표기한다. 언제나 같은 비율로 반지름의 크기에 상관없다.

2πr 이 여기서 나온말이다. r이 반지름이면 2r은 지름이고 원 둘레는 지름의 π배 이기때문이다.

 

 

 

문제2 : 반지름이 3이면 둘레는? [

 

__________________________________________________________________________________________________________________________ 

 radian(라디안) : 호도법으로 호가 반지름과 같아지는 각도. 약 57.3도를 1라디안이라고 하며 보통의 경우 기호를 사용하지 않는다.

 

 

 

문제 3 : 반지름이 2고 각도가 3(radian)이면 호의 길이는 ? [ 6 ]

  ___________________________________________________________________________________________________________________________

 

 

 

관계 :  [문제3]에서 반지름이 0.5면 각도 2π(rad)일 때, 호는 (0.5 x 2π = )를 갖는다. 

      또 [문제2]에서 반지름이 0.5면 각도 360도(원)일 때, 둘레는 (2 x π x 0.5 = )가 됩니다.

여기서 우리는 같은 반지름에서 같은 둘레가 나왔으므로 두 각도 2πrad360도가 같다는 것을 알 수 있습니다.

 180도 = π라디안

 π라디안 = 180도

 1도 = π/180라디안

 1라디안 = 180/π도

 x도 = x*π/180라디안

 x라디안 = x*180/π도

 

___________________________________________________________________________________________________________________________

 

c/c++ 삼각함수 : 두변 길이의 비율을 각도에 따라 나타내어주는 함수와 그의 역함수. 라디안(radian) <==> 비율(ratio) 을 이용한다.

 sin()

 라디안을 받아 비율을 리턴한다.

 sin(rad) = a/h

 cos()

 ..

 con(rad) = b/h

 tan()

 ..

 tan(rad) = a/b

 asin()

 비율을 받아 라디안을 리턴한다.

 asin(a/h) = rad

 acos()

 ..

 acos(b/h) = rad

 atan()

 ..

 atan(a/b) = rad

 

___________________________________________________________________________________________________________________________

이용 방법 : 우리는 radian(라디안)보다 degree(도)에 익숙합니다. 그래서 위의 관계를 방금 배운 지식으로 아래의 관계로 연장합니다.

도(degree) <==> 라디안(radian) <==> 비율(ratio)

 

 

 

 

.

 

 

 

끝!

'프로그래밍 > 참고' 카테고리의 다른 글

자료구조  (1) 2013.03.21
함수 호출규약  (0) 2013.03.20
string  (0) 2013.03.19
string의 메서드  (0) 2013.03.19
바인딩 이야기  (0) 2013.03.11
Posted by 피씨컴

● 자료구조

- by wiki

전산학에서 자료 구조(資料構造, 영어: data structure)는 자료를 효율적으로 이용할 수 있도록 컴퓨터에 저장하는 방법이다. 신중히 선택한 자료구조는 보다 효율적인 알고리즘을 사용할 수 있게 한다. 이러한 자료구조의 선택문제는 대개 추상적 자료구조의 선택으로부터 시작하는 경우가 많다.

 

효과적으로 설계된 자료구조는 실행시간 혹은 메모리 용량과 같은 자원을 최소한으로 사용하면서 연산을 수행하도록 해준다.

 

 

자료구조를 선택하기 위한 요인

- 데이터양

- 데이터를 사용하는 방법과 횟수

- 데이터의 정적 혹은 동적인 특성

- 데이터 구조에 의해 요구되는 기억장치의 양

 

 

 

● 자료구조의 형태에 따른 분류

 

 

 

● 구현에 따라

- by wiki

  • 배열 - 가장 일반적인 구조이다. 메모리 상에 같은 타입의 자료가 연속적으로 저장된다. 자료값을 나타내는 가장 작은 단위가 자료를 다루는 단위이다.
  • 튜플 - 둘 이상의 자료형을 묶음으로 다루는 구조이다.
  • 연결 리스트 - 노드를 단위로 한다. 노드는 자료와 다음 노드를 가리키는 참조값으로 구성된있다. 노드가 다음 노드로 아무것도 가리키지 않으면 리스트의 끝이다.
  • 환형 연결 리스트 - 각 노드는 다음 노드를 가리키고, 마지막 노드가 처음 노드를 가리키는 연결 리스트이다.
  • 이중 연결 리스트 - 각 노드는 이전 노드와 다음 노드를 가리키는 참조값으로 구성된다. 처음 노드의 이전 노드와 마지막 노드의 다음 노드는 없다.
  • 환형 이중 연결 리스트 - 처음 노드가 이전 노드로 마지막 노드를 가리키고, 마지막 노드가 다음 노드로 처음 노드를 가리키는 이중 연결 리스트이다.
  • 해시 테이블 - 개체가 해시값에 따라 인덱싱된다.

 

 

형태에 따라

-by wiki

 

  • 단순구조
    • 정수
    • 실수
    • 문자열
    • 문자
    • 등의 기본자료형

 

  • 선형 구조
    • 스택 - 스택 자료구조에 먼저 저장된 것이 꺼내어 쓸 때는 제일 나중에 나온다. 반대로, 가장 최근에 저장된 것이 꺼내어 쓸 때는 제일 먼저 나온다. 만약, 자료들의 나열 순서를 바꾸고 싶다면 스택에 집어 넣었다가 꺼내면 역순으로 바뀐다.
    • - 스택과 반대로 큐 자료 구조에 먼저 저장된 것이 제일 먼저 나온다. 반대로, 가장 나중에 저장된 것이 꺼내어 쓸 때는 가장 나중에 나온다.
    • 환형 큐 - 한정된 길이 안에서 부수적인 작업 없이 읽고 쓰기를 할 수 있는 큐이다.
    • - 양쪽에서 넣기와 빼기를 할 수 있는 일반화된 선형 구조이다.

 

  • 비선형 구조
    • 그래프 - 정점과 정점을 잇는 간선으로 구성된다.
    • 방향 그래프, 비방향 그래프 - 간선이 방향성을 갖는지 갖지 않는지에 따른 그래프의 분류이다.
    • 트리 - 뿌리 노드와, 뿌리 또는 다른 노드를 단 하나의 부모로 갖는 노드들로 이루어진 구조. 부모 자식 관계는 간선으로 표현된다. 비방향 그래프의 경우, 회로가 없고 연결된 그래프를 뜻한다. 방향 그래프의 경우 간선의 방향은 보통 부모를 가리키도록 구현된다.
    • 이진 트리 - 자식 노드가 최대 두 개인 트리.
    • - 이진트리의 일종으로 이진트리에 어떤 특성을 부여한 것이라 할 수 있다.

 

  • 파일구조
    • 순차파일
    • 색인파일
    • 직접파일

 

 

 

 

 

 

 

 

 

 

 

 

● 스택(Stack)

- 데이터를 건초나 짚더미와 같이 쌓아놓은 형태
- 데이터를 삽입시 스택 아래부터 쌓이며 최신 데이터는 스택의 가장 윗 부분에 위치한다.
- 데이터를 추출(제거)시 스택의 가장 윗 부분에서 꺼내므로 LIFO(Last-In, First-Out) 구조이다.
- 스택을 구현시 배열 기반 또는 링크드리스트 기반으로 구현이 가능하다.
- 배열 기반의 스택의 경우 스택의 크기가 정해져 있다.

스택은 LIFO구조라고 하며, 이는 후입선출 즉 들어온 데이터 순으로 쌓이되 데이터가 나올때는 마지막에 넣은 데이터 순으로 나온다는 특징이

있습니다. 다음과 같은 그림으로 설명할 수 있습니다. 

 

 

 

 

 

 

 

 

큐(Queue)
 - 전단(Front), 후단(Rear)를 가지고 있는 배열과 비슷한 자료구조.
 - FIFO(First In First Out) 선입선출 구조.
 - 전단은 큐의 가장 맨 앞을 가르키고 있으며 후단은 큐의 마지막요소 + 1 을 가리키고 있다.
 - 데이터 삽입시(Enqueue) 후단에 데이터가 삽입되며 데이터 제거시 전단의 데이터가 추출되고 전단의 index는 +1 이 된다.
 - 배열 기반의 큐는 사이즈의 한계가 있다.
 - 배열 기반의 큐는 제거연산을 수행할 수록 전단(Front)의 index가 뒤로 밀려나기 때문에 결국엔 후단 index까지 도달하게 되므로
   상당히 비효율적이다. 그래서 배열 기반 큐의 단점을 해소하기 위해 원형큐(CircularQueue)라는 개념이 나왔다.

 

- 간단히

먼저 들어온사람이 먼저 나간다.
은행에서 순서대로 번호표를 뽑게 하고 번호표 순서대로 일을 처리해주는 예
또는 버스정류장에서 먼저 온순서대로 탑승하는 예

 

 

 

큐는 한쪽 끝은 front로 정해서 삭제 연산만 수행하도록 하고 다른쪽 끝은 rear로 정하여 삽입 연산만 수행하도록 한다.

 

 

 

 

● 선형큐의 문제점

 

 

1차원 배열을 사용하여 큐를 구현하는것을 선형큐라 하는데 포화상태로 인한 문제점이 있다.

rear가 배열의 마지막 위치에 있기 때문에  큐에 자리가 있는데도 포화상태로 인식하고 삽입을 하지 않는다.

 

 

● 선형큐의 문제 해결방법

 

 

1. 저장된 원소를 배열의 앞부분으로 이동시켜서 위치를 조정해주는 방법
But 순차자료에서의 이동 작업은 연산을 복잡하게 하여 효율성을 떨어뜨린다. 


 

 

 

 

 

 

 

원형큐(CircularQueue)
 - 배열 기반의 큐가 원형으로 이루어진 상태.
 - 원형으로 이루어져 있기 때문에 큐가 가득 찼을때나 완전히 비어있을때 Front와 Rear의 index는 동일하므로
   Empty인지 Full인지 구분할 수 없다.
 - 그러므로 원형큐를 생성할때는 더미(Dummy) 공간을 생성하여 원래 용량(capacity)보다 +1 만큼 증가시켜 배열을 생성한다.
   예) 큐의 사이즈 : 9   =>  배열 사이즈 : 10
 - 'Front == Rear'는 비어있는 상태, 'Rear + 1 == Front' 는 가득찬 상태

 

 

1차원 배열을 사용하면서 논리적으로 배열의 처음과 끝이 연결되어 있다고 가정하고 사용
공백 상태와 포화 상태 구분을 쉽게 하기 위해서 front가 있는 자리는 사용하지 않고 항상 빈자리로 둔다.

 

 

원형 큐 연산 과정

 

 

 

1. CreateQueue();                           2. enQueue(A);

3. enQueue(B);                           4. deQueue(A);

 

5. enQueue(C);                                                    6. enQueue(D);

 


 

 


 

 

Stack vs Queue

 

 


 

 

 




 


 

 

'프로그래밍 > 참고' 카테고리의 다른 글

degree(도), π(파이), radian(라디안) 그리고 c/c++ 삼각함수  (1) 2013.04.09
함수 호출규약  (0) 2013.03.20
string  (0) 2013.03.19
string의 메서드  (0) 2013.03.19
바인딩 이야기  (0) 2013.03.11
Posted by 피씨컴

함수를 호출하는 형태에는 여러 가지 방법이 있다. Visual C++에서는 네 가지 형태의 호출 규약을 지원한다. __cdecl, __fastcall, __stdcall, __thiscall이 그것이다. 각 호출 규약은 비슷하지만 약간 씩 차이를 가지고 있다. 각각의 호출 규약에 대한 특징을 살펴 보도록 하자.

__cdecl

C언어 표준 호출 규약이다. 파라미터는 오른쪽에서 왼쪽으로 스택을 통해 전달되며, 호출한 곳에서 스택을 정리한다. 특징적인건 호출한 쪽에서 스택을 정리하기 때문에 가변 인자를 지원한다는 것이다. 

view plaincopy to clipboardprint?

  1. class CCallConv   
  2. {   
  3. public:   
  4.     int ThisCall(int a, int b, int c);   
  5. };   
  6.   
  7. int CCallConv::ThisCall(int a, int b, int c)   
  8. {   
  9.     return printf("%d %d %d\n", a, b, c);   
  10. }  
<TEXTAREA class="wcpp" style="display:none" name=code cols=60>class CCallConv { public: int ThisCall(int a, int b, int c); }; int CCallConv::ThisCall(int a, int b, int c) { return printf("%d %d %d\n", a, b, c); }</TEXTAREA>

호출 하는 코드는 아래와 같다. 특징은 ecx로 클래스의 this 포인터를 전달한다는 점이다.

<PRE>push 3push 2push 1lea ecx, convcall CCallConv::ThisCall</PRE>

스택 정리 방식의 차이

함수 호출 규약의 주된 차이점은 스택 정리 방식이다. 호출한 쪽에서 정리하는 방식과 호출을 당한 곳에서 정리하는 방법이 있다. 호출한 쪽에서 정리하는 방법의 장점은 자신이 파라미터로 전달한 인자의 개수를 정확히 알 수 있기 때문에 가변 인자를 지원할 수 있다는 것이다. 그렇다면 __cdecl을 제외한 나머지 방식은 왜 스택을 호출을 당한 곳에서 정리하는 것일까?

그 이유는 속도에 있다. x86 CPU의 경우 ret 어셈블리 명령어를 두 가지 형태로 지원한다. ret를 하면 단순히 스택에 저장된 복귀 주소로 리턴 한다. 하지만 ret imm16을 사용하면 imm16만큼 스택에서 팝 한 다음 꺼내진 복귀 주소로 리턴 한다. 위에서 살펴 보았듯이 __cdecl은 스택 정리를 위해서 add 명령어가 추가된다. 반면에 호출을 당한 곳에서 정리하는 방식은 리턴할 때에 ret imm16을 사용함으로써 add 명령어가 추가되지 않아도 된다. 또한 486을 기준으로 했을 때 ret와 ret imm16은 5클럭 사이클을 소모하는 동일한 명령어로 처리된다. 따라서 __cdecl보다는 다른 호출 규약이 근소하게 빠를 수 있다.

멤버 함수는 모두 __thiscall??

위에서 멤버 함수엔 __thiscall을 사용한다고 했다. 물론 기본적으로 __thiscall이 사용되나, 직접 지정할 경우 다른 호출 규약을 사용할 수 있다. 다른 호출 규약을 지정하게 되면 첫 번째 인자로 this 포인터가 전달된다.

정리

호출 규약 파라미터 스택 특징
__cdecl 오른쪽 -> 왼쪽 호출한 곳 가변 인자 지원
__fastcall 오른쪽 -> 왼쪽 호출 당한 곳 파라미터 두 개를 ecx, edx를 통해서 전달하기 때문에 두 개 이하의 인자를 가진 함수에 대해서 빠름
__stdcall 오른쪽 -> 왼쪽 호출 당한 곳 Windows 표준 호출 규약
__thiscall 오른쪽 -> 왼쪽 호출 당한 곳 ecx를 통해서 this 포인터를 전달 함

코드

테스트에 사용된 C언어 코드다.

  1. extern "C" int __cdecl CdeclFunc(int a, int b, int c)   
  2. {   
  3.     return printf("%d %d %d\n", a, b, c);   
  4. }   
  5.   
  6.   
  7. extern "C" int __fastcall FastcallFunc(int a, int b, int c)   
  8. {   
  9.     return printf("%d %d %d\n", a, b, c);   
  10. }   
  11.   
  12.   
  13. extern "C" int __stdcall StdcallFunc(int a, int b, int c)   
  14. {   
  15.     return printf("%d %d %d\n", a, b, c);   
  16. }   
  17.   
  18. class CCallConv   
  19. {   
  20. public:   
  21.     int ThisCall(int a, int b, int c);   
  22. };   
  23.   
  24. int CCallConv::ThisCall(int a, int b, int c)   
  25. {   
  26.     return printf("%d %d %d\n", a, b, c);   
  27. }   
  28.   
  29. int _tmain(int argc, _TCHAR* argv[])   
  30. {   
  31.     CdeclFunc(1, 2, 3);   
  32.     FastcallFunc(1, 2, 3);   
  33.     StdcallFunc(1, 2, 3);   
  34.   
  35.     CCallConv conv;   
  36.     conv.ThisCall(1,2,3);   
  37.     return 0;   
  38. }  

<TEXTAREA class="wcpp" style="display:none" name=code cols=60>extern "C" int __cdecl CdeclFunc(int a, int b, int c) { return printf("%d %d %d\n", a, b, c); } extern "C" int __fastcall FastcallFunc(int a, int b, int c) { return printf("%d %d %d\n", a, b, c); } extern "C" int __stdcall StdcallFunc(int a, int b, int c) { return printf("%d %d %d\n", a, b, c); } class CCallConv { public: int ThisCall(int a, int b, int c); }; int CCallConv::ThisCall(int a, int b, int c) { return printf("%d %d %d\n", a, b, c); } int _tmain(int argc, _TCHAR* argv[]) { CdeclFunc(1, 2, 3); FastcallFunc(1, 2, 3); StdcallFunc(1, 2, 3); CCallConv conv; conv.ThisCall(1,2,3); return 0; }</TEXTAREA> 

 

CdeclFunc 함수의 어셈블리 리스팅이다.

PUBLIC  _CdeclFunc
EXTRN   _printf:NEAR
; Function compile flags: /Odt
_TEXT   SEGMENT
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_c$ = 16                        ; size = 4
_CdeclFunc PROC NEAR
; File d:\test\realtest\callconv\callconv.cpp
; Line 7
    push    ebp
    mov ebp, esp
; Line 8
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9623
    call    _printf
    add esp, 16                 ; 00000010H
; Line 9
    pop ebp
    ret 0
_CdeclFunc ENDP


FastcallFunc 함수의 어셈블리 리스팅이다.

_TEXT   ENDS
PUBLIC  @FastcallFunc@12
; Function compile flags: /Odt
_TEXT   SEGMENT
_b$ = -8                        ; size = 4
_a$ = -4                        ; size = 4
_c$ = 8                         ; size = 4
@FastcallFunc@12 PROC NEAR
; _a$ = ecx
; _b$ = edx
; Line 13
    push    ebp
    mov ebp, esp
    sub esp, 8
    mov DWORD PTR _b$[ebp], edx
    mov DWORD PTR _a$[ebp], ecx
; Line 14
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9629
    call    _printf
    add esp, 16                 ; 00000010H
; Line 15
    mov esp, ebp
    pop ebp
    ret 4
@FastcallFunc@12 ENDP
_TEXT   ENDS


StdcallFunc 함수의 어셈블리 리스팅이다.

PUBLIC  _StdcallFunc@12
; Function compile flags: /Odt
_TEXT   SEGMENT
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_c$ = 16                        ; size = 4
_StdcallFunc@12 PROC NEAR
; Line 19
    push    ebp
    mov ebp, esp
; Line 20
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9635
    call    _printf
    add esp, 16                 ; 00000010H
; Line 21
    pop ebp
    ret 12                  ; 0000000cH
_StdcallFunc@12 ENDP
_TEXT   ENDS


ThisCall 함수의 어셈블리 리스팅이다.

PUBLIC  ?ThisCall@CCallConv@@QAEHHHH@Z          ; CCallConv::ThisCall
; Function compile flags: /Odt
_TEXT   SEGMENT
_this$ = -4                     ; size = 4
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_c$ = 16                        ; size = 4
?ThisCall@CCallConv@@QAEHHHH@Z PROC NEAR        ; CCallConv::ThisCall
; _this$ = ecx
; Line 30
    push    ebp
    mov ebp, esp
    push    ecx
    mov DWORD PTR _this$[ebp], ecx
; Line 31
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9653
    call    _printf
    add esp, 16                 ; 00000010H
; Line 32
    mov esp, ebp
    pop ebp
    ret 12                  ; 0000000cH
?ThisCall@CCallConv@@QAEHHHH@Z ENDP         ; CCallConv::ThisCall
_TEXT   ENDS


main 함수의 어셈블리 리스팅이다.

PUBLIC  _main
; Function compile flags: /Odt
_TEXT   SEGMENT
_conv$ = -1                     ; size = 1
_argc$ = 8                      ; size = 4
_argv$ = 12                     ; size = 4
_main   PROC NEAR
; Line 35
    push    ebp
    mov ebp, esp
    push    ecx
; Line 36
    push    3
    push    2
    push    1
    call    _CdeclFunc
    add esp, 12                 ; 0000000cH
; Line 37
    push    3
    mov edx, 2
    mov ecx, 1
    call    @FastcallFunc@12
; Line 38
    push    3
    push    2
    push    1
    call    _StdcallFunc@12
; Line 41
    push    3
    push    2
    push    1
    lea ecx, DWORD PTR _conv$[ebp]
    call    ?ThisCall@CCallConv@@QAEHHHH@Z      ; CCallConv::ThisCall
; Line 42
    xor eax, eax
; Line 43
    mov esp, ebp
    pop ebp
    ret 0
_main   ENDP

참고 자료

http://www.unixwiz.net/techtips/win32-callconv-asm.html
http://home.comcast.net/~fbui/intel.html#clock
http://www.hardwaresecrets.com/article/270/4
http://swox.com/doc/x86-timing.pdf
http://developer.intel.com/design/Pentium4/documentation.htm

'프로그래밍 > 참고' 카테고리의 다른 글

degree(도), π(파이), radian(라디안) 그리고 c/c++ 삼각함수  (1) 2013.04.09
자료구조  (1) 2013.03.21
string  (0) 2013.03.19
string의 메서드  (0) 2013.03.19
바인딩 이야기  (0) 2013.03.11
Posted by 피씨컴

● 함수의 호출 우선순위

 

함수 오버로딩 호출에 대한 우선순위 1 정확한 타입이 정확히 일치 , 2상위의 진급형태(char shot stort int int)

 

메크로 < 일반 지역함수 (1순위 : inline 함수 2순위 일반함수)  < 일반 전역함수 (1순위 : inline함수 2순위 :일반함수) < 특수화템플릿 < 템플릿 함수

 

- 매크로함수는 전처리기로처리가 되고, 인라인 함수는 컴파일러에 의해 처리가 되기 때문에 메크로 함수가 우선된다.

- 지역함수는 해당 지역부터 먼저 함수를 검색하여 이후 밖으로 나가 전역함수를 검색하게 된다.

 

 

기본적인 시그너처 매칭 알고리즘(인수 일치 알고리즘)

※  시그너처 : 함수가 갖는 파라미터들의 리스트를 가리킴.

 

1. 가능하면 정확히 일치되는 것을 찾는다.

2. 표준 형 증진을 시도한다.

3. 표준 형 변환을 시도한다.

4. 사용자 정의 형 변환을 시도한다.

5. 생략부호에 대한 매칭이 있다면 그것을 이용한다.

 

오버로딩딘 함수 선택 알고리즘

1. 비템플릿 함수에 대해 기본 형 변환을 허용하여 정확히 일치되는 것을 선택

2. 함수 템플릿을 이용하여 정확한 일치를 검색

3. 비템플릿 함수에 대해 일반적인 인수 일치 알고리즘을 따름... (여기서 인수일치 알고리즘이란..위의 것)

 

 


● 템플릿 이란?

 

C++ 프로그래머를 위한 강력한 새로운 도구가 "매개변수화 된 형" 또는 템플릿이다

템플릿은 너무나도 유용하여 표준 템플릿 라이브러리(STL, Standard Template Library)가 c++언어에 도입되었다.

계속해서 클래스 및 그의 파생 클래스가 확장되어야하는 상황, 하나에서의 변화가 관련된 모든 클래스로 번지는 상황 등의 문제를 해결한다. 그리고 ANSI 표준을 도입하여 C++에 통합되었다.  c++에서와 마찬가지로 형(type)에 대해 안정되어 있고 매우 융통성이 높다.

 

 

by wiki

템플릿(template)은 C++ 프로그래밍 언어의 한 기능으로, 함수와 클래스가 제네릭 형과 동작할 수 있게 도와 준다. 함수나 클래스가 개별적으로 다시 작성하지 않고도 각기 다른 수많은 자료형에서 동작할 수 있게 한다. 이는 튜링 완전 언어로 볼 수 있다.

템플릿은 C++에서 프로그래머들에게 유용한데, 특히 다중 상속연산자 오버로딩과 결합할 때 그러하다. C++ 표준 라이브러리는 연결된 템플릿의 프레임워크 안에서 수많은 유용한 함수들을 제공한다.

C++ 템플릿은 CLU가 제공하는 매개변수 형태의 모듈과 에이다가 제공하는 제네릭에 영향을 받았다.

 

- 쉽게

무엇을 만들기위해 찍어내는 틀

 


● 템플릿 함수 ?

1. 템플릿을 기반으로 한 함수

2. 함수임 ㅇㅇ

3. 템플릿 함수란 함수 템플릿 즉, 함수 틀로 만들어진 함수(템플릿을 통해 만들어진 함수)로 실제 눈으로는 보이지 않지만 컴퓨터는 컴파일시 저렇게 인식하고 있다?(있는 그것?)

 

 

template <typename T>        //사용자가 만든 함수템플릿을

int sizeof(T a)

{

return sizeof(a);

}

 

예를들어 int 형을 받아왔다 치면 컴파일러는

 

//이렇게 인식하는 이 대상이 템플릿 함수

int sizeof(int a)

{

return sizeof(a);

}

 

 


● 함수 템플릿 ?

함수 템플릿은 함수의 일반화 서술이다. 즉, 함수 템플릿은 int형이나 double형과 같은 구체적인 데이터형을 포괄할 수 있는 일반형(generic type)을 사용하여 함수를 정의한다.

 

1. 함수를 만드는데 사용되는 템플릿 / 함수를 기반으로 구현된 템플릿

2. 함수가 아니라는 뜻

3. 함수 템플릿은 함수를 만들어 낸다 이런 템플릿에 의해 만들어지는 함수의 특징은 기능은 결정되어 있지만 자료형은 결정되어 있지 않다는 것이다.

    즉 같은 기능을 하는 함수도 다양한 자료형을 인자로 호출이 가능하다.

 

- 쉽게

함수를 찍어내는 틀

 

 

template <typename T>

int _sizeof(T a)

{

return sizeof(a);

}

 

//사용

int c=30;

_sizeof<int>(c);//사용 자료형을 명시해줘도 되지만

_sizeof(c);// 안해도 상관없다.

 

 

 

 


클래스 템플릿 ?

클래스 템플릿은 포괄적인 클래스 선언을 생성하는 좀더 나은 방법을 제공한다

템플릿은 매개변수화되는 (parameterized) 데이터형을 제공한다. 즉, 클래스나 함수 설계도에 데이터형 이름을 전달인자로 넘겨주는 기능을 제공한다.

 

클래스 템플릿(class template): 클래스를 찍어내는 틀(template)

 

 

함수 템플릿 처럼, 클래스도 여러개의 데이터형으로 바뀔 수 있는 것을 말한다. 이러한 클래스 템플릿은 컨테이너류에 가장 많이 쓰이며, 대표적인 것으로는 std::vector 가 있겠다.

 

- Class Template 은 템플릿인 클래스. 즉, 클래스 그 자체가 템플릿인 경우를 말합니다.

 

 

template <typename T> class 클래스 이름

{

void 함수이름();

}

 

template <typename T> void 클래스이름<T>::함수이름()

{

//함수 구현부분

}

 

 

 

※ 클래스 템플릿 사용시 하나의 헤더파일안에 함수의 구현과 선언부분을 모두 써줘야한다. 템플릿화 되지 않은 함수도 헤더파일 안에 써줘야한

    다. 그렇지 않으면 링크시 구현부분을 찾지못해 Error가 발생한다.

 

※ 클래스 템플릿은 template <typename T> 을 쓰고 class 클래스이름을 쓴다.

※ 클래스 템플릿 내부의 함수는 클래스 밖 아래에서 구현을 한다.

※ template <typename T>과 클래스이름 <T>를 쓰고 함수 이름을 쓴다.

 

 ※ 오버로딩을 어느정도 대체할순 있지만 완벽하게 대체할순 없다. 클래스 템플릿의 한계가 있기 때문이라는데 ???

 

 

- 또다른 예

template<typename T>

class Data

{

T data;

public:

Data(T d) {data = d;}

void SetData(T d){ data =d; }

T GetData() { return data; }

};

 


 

※ 메인에서 선언할 때는

Data d(10)과 같이 사용하면 문제가 된다.

 

객체 생성순서

메모리 할당 -> 생성자 호출...

 

그러면 Data d(10); 이 문장에서 d이라는 이름으로 메모리 공간을 할당해야 할 것이다. 하지만 우리는 클래스 템플릿을 사용하고 있기 때문에 T가 어떤 데이터 형을 사용해야 할 건지 결정이 나야 메모리 할당이 이루어진다. T가 결정나는 시점은 생성자가 호출되어야만 알 수 있으므로 이전과 같은 문법을 사용한다면 메모리 할당을 전혀 하지 못하게 되는 것이다. 그래서 템플릿 클래스에서 Data 객체를 만들기 위해서는 생성자를 통해서 전달되는 인자의 정보를 참조하는 시기가 늦기 때문에 구체적으로 어떤 타입으로 템플릿을 구체화시킬지 명시적으로 선언해줘야 한다.

 

이렇게

Data<int> d(10);

 

 

 

 


템플릿 클래스 ?

 

Class Template 을 지칭하기도 하며 더불어 템플릿으로 생성된 클래스(인스턴스화된 객체)를 지칭하기도 합니다.

또, 템플릿 식별자로서의 이름을 갖는 클래스를 기리킬 때도 사용합니다.

 

뜻 하는 바가 미묘하게 차이가 나긴 하지만, 무시해도 무방한 것으로 봅니다.

그냥 템플릿으로 작성된 클래스를 지칭하는 것으로 간주하면 되겠습니다.

 


템플릿의 특수화?

특수화란 범위를 좁히는 것을 말한다. 즉 어떠한 경우에서만 특별히 다른 행동을 하는것. 이것이 바로 특수화 이다.

 

 

template <typename T> // 함수 템플릿 정의

int _sizeof(T a)

{

return sizeof(a);

}

template<>                 // 특수화 만약

int _sizeof(char * a)   //char * 타입을 받는다면....

{

return strlen(a);

}

 

int main(void)

{

int in=20;

double f = 1.1;

char * cs = "animo cccc";

 

cout << _sizeof(in)<<endl;

cout << _sizeof(f)<<endl;

cout << _sizeof(cs)<<endl;

}

 


 

Overloading
- 함수의 이름은 같으나 반환 타입이나 인자의 갯수, 인자의 타입이 다른경우 함수를 재정의 하는것

 

int sum(int a, int b) 
{
    return a + b;
}
  
int sum(int a, int b, int c) //overloading
{
    return a + b + c;
}

 

 

 

Overriding
- 상속의 관계에서 부모와 자식의 함수(메서드)가 같은 기능을 수행하지만 함수의 내용이 다른 경우 자식의 클래스에서 함수를 재정의 하는것.
- 함수(메서드)의 이름, return type, 매개변수가 같아야 함
- 접근 제한자의 범위가 부모와 같거나 더 넓어야 함
ex) 부모 - protected, 자식 - public >> O
      부모 - public, 자식 - protected >> X
- Exception 관련 규칙

//Child가 Parent를 상속 받았다고 가정.
void Parent :: whoAmI()
{
    printf("부모입니다.\n");
}
  
void Child :: whoAmI() // overriding
{
    printf("자식입니다.\n");
}
 


 Overloading 과 Overriding 차이

상속관계이냐 아니냐의 차이이며

오버로딩은 같은 이름의 함수가 다른 파라매터값을 받았을 경우를 위한 재정의 이고 

오버라이딩은 리턴 타입과 이름, 파라매터가 모두 동일한 함수가 상속관계에서 서로다른 기능을 하기 위한 재정의 이차이이다.

 

 

 


 

 

 

 

 

● 가상함수(Virtual Function)

- 실행시 사용된 객체에 의해 실행코드가 결정되는 함수

- 지정자 virtual로 선언됨 지정자 virtual은 선언문에 존재함

 

class Animal

{

public:

virtual void breathe();

};

 

class Fish : public Animal

{

public:

virtual void breathe();

};

 

 

 

 

 

● 순수가상함수(Pure Virtual Function)

- 선언만 있고 정의가 없는 가상함수

- 파생 클래스에서 재정의할 것으로 예상되는 함수에 대해 미리 호출 계획을 세워 두기 위해 정의.

 

-가상함수를 순수가상함수로 만드는 방법

선언시 0을 지정하면 됨.

여기서 =0은 Pure Specifier임

 

class Animal

{

public:

virtual void breathe() = 0;

};

 

class Fish : public Animal

{

public:

Fish();

Virtual void breathe();

}

-> Animal::breathe는 순수 가상함수임. Animal::breathe는 함수명만 제공하고, 내용은 Fish::breathe에서 제공하게 됨.

 

- 순수 가상함수는 사용하기 전에 반드시 재정의해야함.

- 만일 기반 클래스가 순수 가상함수를 포함하고 있는데 파생 클래스에서 그것을 재정의하지 않는다면 그 파생 클래스도 추상 클래스가 됨

   -> 기반 클래스 뿐만 아니라, 그 파생 클래스의 객체를 생성하는 것도 불가능함.

 

class Animal

{

public:

virtual void breathe() = 0;

};

 

class Fish : public Animal

{

public:

Fish();

//재정의 안해줌

}

Animal * a = new Animal;    // error  

Animal * f = new Fish;        //error

 

 

http://www.cyworld.com/vcreator/9530269

 

http://blog.daum.net/kingmbc/13597411

 

http://breadlab.net/69

//함수 호출규약

 

 

 

 

 


함수의 호출 우선 순위 조사
일반함수
특수화템플릿
템플릿


템플릿 이란?
템플릿 함수 ?
함수 템플릿 ?
클래스 템플릿 ?
템플릿 클래스 ?
템플릿의 특수화?

//<
오버라이딩
오버로딩의 차이점

 

가상함수
순수가상함수

//< 게임들을 모두 Game기반으로 상속받아서 처리할것
//< 공용함수등을 Game으로 만들어볼것

 

 

'프로그래밍 > 공부' 카테고리의 다른 글

API 2장  (0) 2013.04.16
AIP 1장  (0) 2013.04.16
3/8  (0) 2013.03.11
3/7  (0) 2013.03.11
3/5  (0) 2013.03.07
Posted by 피씨컴