검색결과 리스트
분류 전체보기에 해당되는 글 43건
- 2011.10.24 8. 비트맵과 이미지처리
- 2011.10.20 데이터처리
- 2011.10.18 C++시작하기
- 2011.10.12 MFC 5장 키보드 입력
- 2011.10.12 MFC1장
- 2011.10.12 MFC3장 -MFC코드의 기본구조
- 2011.10.12 Point?!
- 2011.09.17 I.객체지향 방법론
- 2011.09.17 현재 보유 컴
- 2011.08.23 Const
글
- 윈도우 프로그래밍에서 비트맵 이미지를 출력하는 전형적인 방법은 리소스로 등록된 비트맵 이미지를 메모리 DC에 로드 하여
화면 DC로 출력(BitBlt())하는것입니다. 이과정을 요약하면, 이미지의 크기를 변경(StretchBlt())하거나 일부영역을 투명하게
처리(TransparentBlt())하거나 반투명하게 처리(AlphaBlend())하게 됩니다.
비트맵은 장치의존적인 비트맵(DDB, Device Dependent Bitmap)과 장치 독립적인 비트맵 (DIB, Device Indepent Bitmap)으로
나누어집니다. 장치 의존적이냐 장치 독립적이냐는 말은 장치의 영향을 받느냐 그렇지 않느냐의 의미로 해석 됩니다.
우리가 아는 비트맵파일은 모두 DIB라고 봐도 무방합니다. 비트맵을 우리눈으로 보려면 DDB로 변환해야합니다.
비트맵을 저장할 메모리 DC를 생성하되 출력할 화면 DC와 호환이 되도록합니다. 그리고 비트맵을 로드하고 메모리 DC의
비트맵으로 선택합니다. 최종적으로 BitBlt()함수를 호출하여 메모리 DC에 로드된 비트맵 이미지를 화면 DC로 전송합니다.
화면 DC로 비트맵을 전송하면 내부적으로 DIB가 DDB로 변환되어 모니터 화면에 출력하게됩니다.
CDC클래스의 CreateCompatibleDC() 메서드는 CDC클래스 객체의 주소를 인자로 받으며 전달받은 CDC클래스 객체와 호환되는
메모리 DC를 생성합니다. 메모리 DC는 출력할 비트맵 이미지를 저장하는 메모리 공간이라 할수있습니다.
CDC클래스의 BitBlt() 함수는 메모리 DC에서 화면 DC로 비트맵을 전송해 줍니다.
BitBlt()원형
BitBlt()함수는 메모리 DC에서 이미지의 일부 혹은 전체를 뗴어서 화면 DC로 전송합니다.
함수의 x,y인자는 화면 DC에서 출력을 시작하는 좌표.
nWidth,nHeight 인자가 각각 250,300 이되었는데, 화면DC에서 출력할 이미지의 크기를 말합니다.
xSrc,ySrc 인자는 출력할 원본이미지를 시작하는 좌표입니다.
원본이미지의 폭과 높이는 명시하지않았지만, 출력할 이미지와 같은 크기로 잘라냅니다.
BitBlt()함수의 마지막 인자에는 래스터 연산을 어떻게 할지 명시하는데,SRCCOPY는 메모리 DC의 내용에 변화를 주지 말고 그대로
화면DC에 복사 하라는 의미.
dwRop연산
BLACKNESS | 검정색으로 채운다 |
WHITENESS | 흰색으로 채운다 |
DSTINVERT | 화면을 반전 |
MERGECOPY | 소스 비트맵과 바탕화면을 AND연산한다. |
MERGEPAINT | 소스 비트맵과 바탕화면을 OR연산한다. |
SRCCOPY | 소스영역을 대상 영역에 복사한다. |
SRCAND | 타겟과 AND연산. |
SRCINVERT | 타겟과 XOR연산 |
SRCPAINT | 타겟과 OR연산 |
SRCERASE | 타겟과 NOT소스를 AND |
가령 폭과 높이가 300*200인 비트맵 이미지가 있다면 200개의 수평선이 있는 이미지를 의미. 래스터 연산을 한다는것은
이미 화면에 출력된 래스터와 출력할 래스터를 어떻게 조합할것인지를 연산하는것입니다. 즉, 각각의 픽셀 하나하나에
대해 AND,OR,XOR과 같은 비트 연산을 하는 것입니다. 따라서 이값을 어떻게 조합하느냐에 따라 화면 이미지를 덮어쓰게
되기도 하고 일정 부분 섞여서 출력하기도 합니다.
StrechBlt()함수는 BitBlt()함수처럼 메모리 DC에 로드된 비트맵 이미지를 화면 DC에 출력하는 기능을 한다는 점에서는 같지만
원본 크기와 대상 크기를 달리하여 이미지를 확대 축소 출력한다는 점이 다름.
■고급 이미지 출력 함수
TransparentBlt()와 AlphaBlend() 두함수는 모두 예전에는 CDC클래스의 맴버가 아니였으나, MFC를 업그레이드 하면서 맴버로
추가되었습니다.
TransparentBlt()함수와 StretchBlt()함수 인자가 거의 비슷합니다.
StretchBlt()함수의 마지막 인자는 래스터 연산값이지만, TransparentBlt() 함수의 마지막 인자는 투명하게 출력할 RGB값입니다.
위의 소스에서 RGB값이(0,0,0)이므로 검정색이 됩니다. 따라서 메모리 DC에 로드된 비트맵의 색상중에 검정색은 투명하게 출력
될것입니다.
AlphaBelnd()함수는 전체이미지를 반투명하게 만듭니다.
AlphaBlend()함수의 마지막 인자 BLENDFUNCTION구조체는
BlendOp 맴버에는 원본이미지와 대상이미지를 섞는 연산을 명시합니다.
AC_SRC_OVER은 원본/대상 이미지를 서로 섞는다는 의미.
BlendFlags 맴버는 사용하지않으면 반드시 0이어야함.
SourceConstantAlpha 맴버는 원본이미지의 투명도를 결정하며 0~255범위값을 같습니다.
0이면 완전 투명(아무출력하지않음.) 255면 완전히 불투명해집니다.
BLENDFUNCTION 구조체의 마지막 맴버인 AlphaFormat에는 원본과 대상 비트맵 이미지를 해석하는 방법을 명시합니다.
이값은 0이나 AC_SRC_ALPHA가 되어야합니다.
AC_SRC_ALPHA가 되는 경우 원본 비트맵이 24비트 이하의 비트맵이 아니라 각 픽셀에 대한 알파 채널을 갖는 진정한 32비트
비트맵인경우에만 해당합니다.
■CImage 클래스의 활용
CImage 클래스는 MFC가 제공하는 ATL 클래중하나입니다. 그러므로 내부적으로는 COM객체로 구현되어 있습니다.
C++의 클래스가 논리적인 코드를 객체화한 개념이라면 COM은 실행 바이너리 파일 단위로 객체화한 것이라고 할수있다.
그러므로 메서드가 반환하는 값은HRESULT형이며, FAILED()매크로나 SUCCEEDED()매크로를 이용해 오류를 확인합니다.
CImage클래스의 Load() 메서드는 인자로 전달받은 경로의 이미지 파일을 로드하여 DIB이미지를 생성합니다.
유사 함수로 LoadFromResource()메서드가 있습니다. 이 함수는 CBitmap 클래스의 LoadBitmap() 메서드처럼 비트맵 리소스를
로드하여 비트맵 이미지를 만듭니다.사용하는 인자도 리소스 ID를 주어야한다는 점에서 같지만 첫번째 인자로 ::LoadImage() API
함수처럼 응용프로그램의 인스턴스 핸들을 주어야합니다.
메모리DC를 이용한 전형적인 이미지 출력보다 훨씬 코드가 간단해집니다.
CImage 클래스에는 GetDC()와 ReleaseDC()메서드가 있습니다.이들메서드는 CDC클래스의 GetDC()와 ReleaseDC()함수와 유사
합니다.다만, 생성한 비트맵 객체가 이미 있다는점에서 차이가 납니다.
구현방법은 화면 DC에 이미지를 출력한 다음에 추가로 문자열을 화면 DC에 출력하는 방법과 이미지DC에 문자열을 출력하고
변경한 이미지를 화면 DC에 출력하는 방법이있습니다. 별다를것없이 보이지만 화면의 깜빡임을 제거하는 코드를 만들려면
두방법은 극단적인 차이를 보입니다.
GetDC()메서드를 이용하면 DC의 핸들인 HDC데이터를 반환합니다. MFC의 CDC클래스는 내부적으로 m_hDC라는 핸들 맴버를
갖고있습니다. 이것은 CWnd클래스가 윈도우 핸들맴버로 갖는것과 비슷합니다. 그리고 CDC 클래스의 정적 맴버인 FromHandle()
함수를 명시적으로 호출하여 HDC에 대한 CDC클래스 객체의 포인터를 반환받습니다.
CDC클래스 객체는 CImage클래스 객체와 연결된 메모리DC가 되는데, 이것을 앞서배운 메모리DC와 구별하기위해 이미지DC라고
부릅니다. 이미지DC는 CImage 클래스 객체와 연결되어있으므로 나중에 CImage::ReleaseDC()메서드를 호출하여 리소스반환.
문자열의 배경을 투명하게 하고 TextOut() 함수를 이용하여 이미지 DC에 문자열을 출력하는 코드입니다.
함수의 원형| Bitblt()
■색상의 변환
윈도우 프로그래밍에서는 이미지를 처리할때 RGB방식을 사용합니다. 하지만, HSB/HSV색상, Saturation 명도, Brightness 밝기,
Value깊이 방식을 사용하여 색상을 표현하기도 합니다.
RGB컬러를 흑백으로 변환하는 방법은 매우간단하며 공식처럼 활용됩니다.
GetRValue(), GetGValue(), GetBValue() 함수는 COLORREF값에서 RGB값을 각각 추출하는 매크로입니다.
24비트 컬러에서 각각은 8비트이며, RGB각각에 대해 30,59,11을 곱한 값을 모두더해 다시 100으로 나누면 흑백에 해당하는
값을 구할수 있습니다.
CWnd 클래스의 GetDesktopWindow() 메서드는 바탕화면 윈도우 객체의 포인터를 반환합니다.
이렇게 해서 알아낸 바탕화면에 대한 DC를
로 생성합니다. 이때 CPaintDC클래스나 CClientDC클래스를 사용하지않고 CWindowDC클래스를 사용한것은.
CWindowDC클래스는 다른 형제 DC들과 달리 비클라이언트 영역을 포함한 윈도우 전체에 대한 DC입니다.
비트맵 파일이나 리소스를 로드하는것이 아니라 폭과 높이가 각각 300픽셀이고 바탕 화면 윈도우 DC의 픽셀당 비트수가 같은 비트맵
이미지를 생성합니다. CDC클래스의 GetDeviceCaps()메서드는 DC의 각종 정보를 추출합니다.인자로 전달받은 인덱스에따라
각각 다른 값을 int형 값으로 반환합니다.
일부이미지(200*200)을 흑백으로 변환(RGBtoGray)합니다. 이과정에서 CImage클래스의 GetPixel()과 SetPixel() 함수를
사용하였는데, 비트맵 이미지를 2차원 배열이라고 가정하고 원하는 특정 지점의 좌표를 이용하여 RGB값을 가져오거나 실행합니다.
같은 이름의 함수가 CDC클래스에도 있으며 기능도 같습니다. 이렇게 일부 영역의 이미지를 흑백이미지로 변환하여
화면에 출력하고 모든 처리를 종료합니다.
CImage클래스의 Create()메서드의 원형
마지막 인바의 기본값은 0입니다. 이인자에는 32비트 비트맵일경우 알파 채널을 명시합니다. 세번째인자(nBPP)가 반드시 32가 되어야 알파 채널을 명시할수 있습니다.
CDC클래스의 GetDeviceCaps()메서드는 인자로 전달받은 인덱스에 해당하는 DC정보를 반환해줍니다.
윈도우 탐색기는 윈도우 운영체제의 셀입니다. ::ShellExecute() API함수의 원형은 다음과 같습니다.
함수의원형 | ShellExecute()
hwnd 인자는 부모 윈도우의 핸들이며, 이값이 NULL이면 부모윈도우는 바탕화면이 됩니다.
lpOperation 인자에는 함수가 어떤 동작을 할것인지 명시합니다.
lpFile인자와 연결된 프로세스를 실행하라는 의미.
lpFarameters 인자에는 lpFile인자가 싱행 파일인 경우 실행할 파일의 실행인자를 명시합니다.
lpDirectory 인자에는 실행할 프로그램의 현재 폴더 경로를 명시합니다. 이값이 NULL이면 윈도우 기본 설정을 적용 합니다.
'WindowPrograms > MFC' 카테고리의 다른 글
MFC 5장 키보드 입력 (0) | 2011.10.12 |
---|---|
MFC1장 (0) | 2011.10.12 |
MFC3장 -MFC코드의 기본구조 (0) | 2011.10.12 |
설정
트랙백
댓글
글
■간단한 변수
braincount=5;
이명령문만 보고는 그값이 메모리의 어디에 저장되는지는 알수 없다 그러나 프로그램은 그위치를 추적할수 있다.
사용자도 &연산자를 사용하면 braincount의 메모리 주소를 알아낼수 있다.
■변수 이름
C++에서 변수 이름을 지을때에는 다음과 같은 간단한 규칙에 따라야한다.
ⓐ변수 이름에는 영문자, 숫자, 밑줄(_) 문자만을 사용할수 있다.
ⓑ숫자를 변수 이름의 첫문자로 사용할수 없다.
ⓒ변수 이름에서 대문자와 소문자는 구별된다.
ⓓC++ 키워드는 변수 이름으로 사용할 수 없다.
ⓔ두개의 밑줄친 문자로 시작하는 이름이나, 밑줄 문자와 대문자로 시작하는 이름은, 그것을 사용하는 컴파일러와 리소스가
사용하기로 예약되어있다. 하나의 밑줄 문자로 시작하는 이름은, 그것을 사용하는 컴파일러와 리소스가 전역 식별자로 사용하기로
예약되어있다.
ⓕ변수 이름의 길이는 제한이 없으며, 변수이름에 쓰인 모든 문자들이 유효하다.
- 두개 이상의 단어를 결합하여 변수이름을 지을때는, my_onions와 같이 밑줄로 단어를 구분하거나, myEyeTooth와 같이 첫단어를 제외하고 각단어들의 첫문자를 대문자로 쓰는것이 관례이다.
■ 정수형
C++은 여러가지 정수형을 제공한다.
이것은 프로그램이 요구하는 특정상황에 가장 알맞은 정수형을 골라서 사용할수 있도록 하기 위해서이다.
C++의 여러 정수형들은 서로 다른 크기의 메모리를 사용하여 정수를 저장한다.
메모리 블록이 클수록 나타낼수 있는 정수값의 범위가 크다. signed데이터 형은 양수값과 음수값을 모두 나타낼수 있으나, unsigned데이터형은 양수값만 나타낼수있다. 정수를 저장하는 데 사용되는 메모리 크기를 폭(width)라 한다. 메모리 크기가 클수록 폭이 넓다. C++의 기본 정수형을 크기 순서로 나열하면 char,short,int,long순이다. 이 기본형들에 대해 signed형과 unsigned형이 각각 따로
존재한다.
■short,int,long 정수형
컴퓨터의 메모리는 비트(bit) 단위로 이루어진다.
C++에서 short,int,long은 정수를 저장하는데 사용하는 비트수가 다르다.
C++는 이 데이터형들의 최소 크기만을 정하여 보다 융통성있는 표준을 제공한다.
●short형은 최소한 16비트 폭을 가진다.
●int형은 최소한 short만큼 크다.
●long형은 최소한 32비트 폭을가지며, 최소한 int만큼은 크다.
C++들이 short형을 16bit로 , long형을 32bit로 사용하는 최소 보증 표준을 따르고있다. 그러나 int형에 대해서는 폭이 16,24,32가 될수있다.
일반적으로 IBM용 구식 C++에서는 int형이 16비트이다. windows 98,XP,NT,OSX등에서는 C++의 int형이 32bit이다.
다른 데이터형들의 변수도 int형 변수처럼 선언할수 있다.
int temperature; //int형의 정수형 변수를 만든다.
long position; //long형의 정수형 변수를 만든다.
int,short,long 세가지 데이터형은 부호가 있는 데이터형으로서, 나타낼수 있는 양의 정수값과 음의 정수값 범위가 거의 같다.
C++ 시스템의 정수크기가 얼마인지 알고 싶으면, 데이터 크기를 알아내는 C++도구를 사용할수 있다.
첫번째 방법은 sizeof연산자를 사용하는 것이다. sizeof연산자는 변수나 데이터형의 크기를 바이트 단위로 리턴한다.
'바이트'의 의미는 컴파일러에 따라 다르므로 2바이트 int형이 어떤 C++에서는 16비트인반면, 어떤컴퓨터에서는 32비트가 될수도있다.
두번째 방법은 여러가지 정수 형들의 범위에 대한 정보가 있는 climite헤더파일을 열어보는것이다.
▣climits에 정의 되어있는 기호 상수들
기호상수 | 의미 |
CHAR_BIT | char형의 비트수 |
CHAR_MAX | char형의 최대값 |
CHAR_MIN | char형의 최소값 |
SCHAR_MAX | signed char형의 최대값 |
SCHAR_MIN | signed char형의 최소값 |
UCHAR_MAX | unsigned char의 최대값 |
SHRT_MAX | short 형의 최대값 |
SHRT_MIN | short형의 최소값 |
USHRT_MAX | unsigned short형의 최대값. |
INT_MAX | int의 최대값 |
INT_MIN | int의 최소값 |
UINT_MAX | unsigned int 의 최대값 |
LONG_MAX | longt의 최대값 |
LONG_MIN | long의 최소값 |
ULONG_MAX | unsinged long형의 최대값 |
■unsigned형
- unsigned형을 사용하면 그변수에 저장할수 있는 최대값을 늘릴수 있다. 예를들어 short형이 -32768에서 +32767까지의 범위를
갖는다면, unsigned short는 0부터 65535까지의 범위를 갖는다. 물론 unsigned형은 인구수,낱알수, 웃는 얼굴 표정수와 같이 결코
음수가 될수 없는 양을 나타낼 때만 사용해야한다.
■정수형 상수
정수형 상수는 212,1776과 같이 프로그램에 직접 써넣는 정수를 말한다.
정수형상수에는 세가지 방법이있다. 일상생활에서는 사용하는 10진수, 구식 Unix가 사용하던 8진수, 하드웨어 전문가가 좋아하는
16진수.
C++에서는 상수의 처음하나의 숫자 또는 처음 두개의 문자가 진수를 의미한다.
처음 숫자가 1~9이면 그수는 10진수이다. 처음 숫자가 0이고 두번째 숫자가 1에서7이면 그수는 8진수이다.
따라서 042는 8진 정수형 상수이며, 10진수로는 34이다. 그리고 처음 두개의 문자가 0x또는 0X이면 16진수를 나타낸다.
0x42는 16진 정수형 상수이며 10진수로 66이다. 그런데 16진 정수형 상수를 나타내는데쓰이는 A~F까지의 문자는 10진수로 각각 10에서 15까지 해당하는 16진수 숫자이다. 그러므로 0xF는 10진수로 15이고 0xA5는 10진수로 10x16+5,즉 165이다.
■C++가 상수의 데이터형을 결정하는 방법
C++에서는 특별한 이유가 없다면 정수형상수를 모두 int형으로 저장한다.
그러나 특정 데이터형을 의미하는 접미어를 상수에 붙였을때와 , 값이 너무커서 int형으로 저장할수 없을때에는 그렇지않다.
접미어에 대해 알아보자.
접미어는 상수 끝에 붙는 문자로서 그 상수의데이터형을 나타낸다. l이나Ldms long형을 의미하고 u나U는 unsigned int형을 의미.
ul은 unsigned long형을 의미,(ul의 l은 숫자1과 혼동하기 쉬으므로 대문자L로 사용한다.)
16비트 int형과 32비트 long형을 사용하는 시스템에서, 22022는 16비트 int형으로 저장되고 , 22022L은 32비트 long형으로 저장된다.
그리고 22022LU와 22022UL은 unsigned long형으로 저장된다.
C++는 16진수 정수나 8진 정수에 적용하는 규칙과는 약간 다른 규칙을 10진수 정수에 적용하고있다.
접미어가 없는 10진 정수는 int,long,unsigned long형중에 크기가 가장작은것으로 나타낸다.
예를들면, 16비트 int형과 32비트 long형을 사용하는 시스템에서, 20000은 int형으로, 40000은 long형으로 300000000은 unsigned
long형으로 나타낸다. 또한 접미어가 없는 16진 정수나 8진 정수는 int,unsigned int , long, unsigned long형 중에 크기가 가장작은
것으로 나타낸다. 그이유는 성질상 부호가 없는 메모리 주소를 일반적으로 16진수로 나타내기 때문이다.
그래서 16비트 주소를 나타내는데는 long형보다 unsigned int형이 적당하다.
■char형: 문자와 작은 정수
char형은 이름에서 알수 있듯이, 문자와 숫자를 저장하기 위한것이다.
char형은 실제로 또 하나의 정수형이다. 컴퓨터 시스템에서 사용하는 문자와 숫자, 구두점과 같은 기본적인 기호들을 모두 char형
으로 나타낼수있다. 대부분의 컴퓨터 시스템들은256개 보다 적은 개수의 문자들을 지원한다.
이러한 문자들은 1바이트만으로 충분히 나타낼수 있다. 그러므로 char형은 문자들을 처리하는 데 사용할수 있고, short형보다 작은 범위의 정수를 나타내는데 사용할수 있다.
예를들어 65는 문자 A에 해당하는 코드이고, 77은 문자M에 해당하는 코드이다.
ASCII나 EBCIDC은 국제적인 요구를 모두 수용하지 못한다. 그래서 C++는 보다 넓은 범위의 값을 수용하는 Unicode국제 문자 세트
를 사용할수 있는 확장 문자형을 지원한다 그러한 데이터형을 wchar_t형이다.
char형 A에 해당하는 숫자는 65이다.
-cout.put()란?
cout.put()은 C++객체 지향 프로그래밍에서 중요한 개념인 맴버함수를 설명할수 있다.
클래스는 데이터 형식과 그 데이터를 다루는 방법을정의 해놓은 것이다.
맴버 함수는 클래스에 속하고, 클래스의 데이터를 다루는 방법을 정의한다.
예를들어, ostream클래스는 문자를 출력하도록 설계된 put()이라는 맴버함수를 가지고있다.
맴버함수는 그 클래스의 특정 객체를 통해서만 사용할수 있다. cout객체를 통해 put()이라는 맴버함수를 사용한다. cout과 같은
객체를 통해 멤버함수를 사용하려면 마침표(.)로 객체이름(cout)과 함수이름(put())을 서로연결해야한다.
이마침표를 멤버연산자라고 부른다. cout.put()이 나타내는 의미는 클래스 객체인 cout을 통해 클래스 멤버함수인 put()을 사용하겠다는 뜻이다.
cout.put 맴버함수는 << 연산자를 사용하여 문자를 출력하는 것에 대한 대안이다.
그런데 여기서 cout.put()이 왜 필요한가?
그것은 C++ Release 2.0 이전에 cout은 문자 변수들을 문자로 출력했지만, 'M'이나 'N'과 같은 문자 상수들은 수로 출력했다. 이문제는 C와 C++초기 버전들이 문자 상수를 int형으로 저장하는데서 비롯되었다.
즉, 문자상수'M'에 해당하는 코드 77이 16비트 또는 32비트로 저장되었다. 그러나 cahr형 변수는 8비트만 차지했다.그래서 다음과 같은 명령문은
이것은 문자상수'M'과 char 변수 ch가 동일한 값을 가지고 있더라도 cout에게는 서도 다르게 보였다는것을 의미한다.
그래서 다음과 같은 명령문은
문자$를 출력하지않고. '$'에 해당하는 ASCII코드 36을 출력했다. 그러나 다음 과 같은 명령문은
cout.put('$');
원하는 대로 문자 $를 출력했다. C++ Release2.0 이후에 모든 C++들은 문자상수를 int형이 아닌 char형으로 저장한다.
그래서 이제는 cout이 문자상수를 바르게 처리할수 있게되었다.
■만국 문자 이름
- C++는 특정 키보드와 무관한 국제 문자들을 표현하는 메커니즘도 가지고있다. 그것을 만국문자이름(Universal character names)
라고 한다.
●signed char형과 unsigned char형
-int 형과는 달리, char형은 signed형이나 unsigned형으로 미리 정해져있지않다. 이것은 개발자가 하드웨어 특성에 맞추어 알맞은
char형을 정할수 있도록 하기위한 배려이다. 그러나 char형이 어느 특별한 한가지 행동만을 보여야한다면, signed char형 또는
unsigned char형을 사용하여 그행동을 명시적으로 제한할수 있다.
unsigned char bar; //unsigned형 char
signed char snark; //signed형 char
unsigned char형은 0에서 255까지의 범위를 나타낼수 있고, signed char형은 -128부터 127까지의 범위를 나타낼수있다.
예를들어,200정도 되는 값을 char형 변수에 저장한다고 하면 이것은 어떤 시스템에서는 동작하지만 다른 어떤 시스템에서는 동작하지 않을것이다. 같은 값을 unsigned char형에 저장한다면 어느 시스템에서나 무리없이 동작할것이다. 그러나 표준ASCII문자를 char형
변수에 저장할때에는 signed형이나 unsigned형이나 상관없으므로 간단히 char이라고 쓰면 된다.
●확장 char형: wchar_t
-프로그램이 1바이트(8bit)로 표현할수 없는 문자세트(일본어,중국어,한글등)를 처리 해야할때에쓰인다.
C++에서는 두가지 방법으로 처리 한다.
첫번째, 확장 문자 세트가 시스템의 기본 문자 세트이면, 컴파일러 개발업체가 char형 을 처음부터 2바이트(16bit)또는 그이상으로
만드는것.
두번째, 기본문자 세트와 확장 문자세트를 동시에 지원하느것이다. 즉, 보통의 8비트 char형 으로 기본 문자세트를 나타내고,
wchar_t형으로 확장 문자세트를 나타내는것이다.
wchar_t형은 시스템에서 사용되는 가장 큰 확장 문자 세트를 나타낼수 있을만큼 충분한 비트 폭을 가진 정수형이다.
wchar_t형은 기초데이터형 이라고 부르는 정수형과 동일한 크기와 부호 속성을 가진다. 기초 데이터형은 시스템에 따라 다른데,
어떤 시스템에서는 unsigned short형일수도있고, 다른시스템에서는 int형이 될수도있다.
확장문자상수나 확장 문자 문자열은 그앞에 L을 붙여서 나타낸다. 다음과 같은 코드는 변수 bob에 문자 P의 wchar_t형버전을
저장하고, 단어 tall의 wchar_t형 버전을 디스플레이한다.
wcout <<L"tall"<<endl; //확장 문자 문자열의 출력
2바이트 wchar_t 형을 사용하는 시스템에서, 이코드는 각문자에 2바이트씩 할당하여 메모리에 저장한다.
●bool형
-bool형 변수는 참이나 거짓 어느 한가지 값만 가질수 있다. On / Off 스위치라 생각하면 쉽다.
C++는 0이 아닌값들을 참으로, 0인값을 거짓으로 해석한다.
int ans = true; //ans 에 1이되입된다.
int promise = false; //promise에 0이 대입된다.
어떠한 수치 값이나 포인터 값도 하나의 bool값으로 묵시적으로 변환될수 있다.
bool stop = 0; //stop에 false가 대입
■const 제한자
- #define문보다 쉽게 기호 상수를 다루는 방법은 const키워드를 사용하여 변수를 선언하고 초기화 하는 것이다.
1년의 달수를 기호 상수로 나타내고 싶다면
MONTH와 같은 상수는 한번 초기화 되면 그값이 '고정' 된다. 컴파일러는 이후 MONTH의 값을 변경하려는 어떠한 시도도 허용하지
않는다.
키워드 const는 선언의 의미를 제한하므로 제한자라고 부른다.
일반적으로 관행은,MONTHS가 상수라는 것을 금방알수있도록 이름을 모두 대문자로 쓰거나,또다른 관행은 상수이름의 첫문자만
대문자로 쓴다던지, kmonth처럼 앞에다가 k를 넣는것이다.
상수를 만드는 일반적인 형식은 다음과 같다.
const 상수는 선언할 때 초기화해야 하며, 다음과 같이 하는것은 좋지않다
---
const int toes; //toes값은 미확정
toes= 10;
const상수는 선언할때 값으로 초기화 하지 않으면 변경할수 없는 미확정값으로 남겨진다.
#define보다 const를 사용하는게 좋은이유는
첫번째, 데이터형을 명시적으로 지정할수 있다는점.
두번째, C++의 활동범위 규칙에 의해 그 정의를 특정함수나 파일에만 사용할수 있도록 제한할수있다는점.
세번재, 배열이나 구조체 와 같은 복잡한 데이터 형에도 const를 사용할수 있기때문.
■연산자 우선순위
===C++연산자 우선순위와 결합 규칙====
연 산 자 | 결 합 규 칙 | 의 미 |
우선 순위 그룹1 | ||
:: | 사용 범위 결정 연산자 | |
우선 순위 그룹 2 | ||
(expression) | 괄호묶기 | |
() | L-R | 함수호출 |
() | 값생성, 즉 type(expr) | |
[] | 배열 첨자 | |
-> | 간접 맴버 연산자 | |
. | 직접 맴버 연산자 | |
const cast | 특수화된 데이터형 변환 | |
dymic cast | 특수화된 데이터형 변환 | |
reinterpret cast | 특수화된 데이터형 변환 | |
static cast | 특수화된 데이터형 변환 | |
typeid | 데이터형 인식 | |
++ | 증가 연산자, 접미어 | |
-- | 감소 연산자, 접미어 | |
우선순위 3그룹(단항) | ||
! | R-L | 논리부정 |
~ | 비트 부정 |
+ | 단항 플러스(양수부호) | |
- | 단항 마이너스(음수부호) | |
++ | 증가 연산자, 접두어 | |
-- | 감소 연산자, 접두어 | |
& | 주소 | |
* | 내용 참조(간접 값) | |
() | 데이터형 변환(type) expr | |
sizeof | 바이트 단위의크기 | |
new | 동적으로 메모리할당 | |
new[] | 동적으로 배열 할당 | |
delete | 동적으로 할당된 메모리해제 | |
delete[] | 동적으로 할당된 배열 해제 | |
우선순위 4그룹 | ||
.* | L-R | 맴버내용 참조 |
->* | 간접 맴버내용 참조 | |
우선순위 5그룹(2항) | ||
* | L-R | 곱셉 |
/ | 나눗셈 | |
% | 나머지 | |
우선순위 6그룹(2항) |
+ | L-R | 덧셈 |
- | 뺄셈 | |
우선순위 7그룹 | ||
<< | L-R | 비트들을 왼쪽으로 시프트 |
>> | 비트들을 오른쪽으로 시프트 | |
우선순위 8그룹 | ||
< | 보다 작다 | |
<= | 보다 작거나 같다 | |
>= | 보다 크거나 같다 | |
> | 보다 크다 | |
우선순위9그룹 | ||
== | L-R | 같다 |
!= | 같지않다 | |
우선순위10그룹(이항) | ||
& | L-R | 비트 AND |
우선순위 11그룹 | ||
^ | L-R | 비트 XOR |
우선순위 12그룹 | ||
| | L-R | 비트 OR |
우선순위 13그룹 | ||
&& | L-R | 논리AND |
우선순위 14그룹 | ||
|| | L-R | 논리OR |
우선순위 15그룹 | ||
?: | R-L | 조건식 |
우선순위 16그룹 | ||
= | R-L | 단순대입 |
*= | 곱셈후대입 | |
우선순위 17그룹 | ||
/= | 나눗셈후 대입 | |
%= | 나머지셈 후 대입 | |
+= | 덧셈후 대입 | |
-= | 뺄셈후 대입 | |
&= | 비트 AND후 대입 | |
^= | 비트 XOR후 대입 | |
|= | 비트 OR후 대입 | |
<<= | 왼쪽으로 시프트후 대입 | |
>>= | 오른쪽으로 시프트후 대입 | |
우선순위 18그룹 |
throw | L-R | 예외발생 |
우선순위 19그룹 | ||
, | L-R | 두 수식을 하나로 결합 |
■데이터형 변환
C++는 데이터형의 불일치를 해결하기 위해 다음과 같은 상황일때자동으로 데이터 형 변환을 수행한다.
●특정 데이터형의 변수에 다른 데이터형의 값을 대입했을때
●수식에 데이터형을 혼합하여 사용했을때
●함수에 전달인자를 전달했을때.
◎대입명령문에서 데이터형변환
-범위가 작은 데이터형의 값을 범위가 큰 데이터형에 대입하는것은 문제가 되지않는다. 하지만 short형 값을 long형 변수에
대입하면 값은 변하지 않고 의미없는 여분의 바이트만 추가된다. 그러나 21112222333과 같은 큰 long형 값을 float형변수에
대입하면 정밀도가 손실된다.
데이터형변환에서 일어날수있는 잠재적문제는 다음과 같다.
데이터 형변환 | 잠재적 문제점 |
double→float와 같이 큰부동 소수점형을 작은 부동 소수점형으로 |
정밀도(유효숫자)가 손실된다. 원래의 값이 변환 데이터의 범위 를 벗어날경우, 결과를 예측할수없다. |
부동 소수점형을 정수형으로 | 소수부를 잃어버린다. 원래값이 변환 데이터형의 범위를 벗어날 경우, 결과를 예측할수없다. |
long→ short와 같이 큰정수형을 작은 정수형으로 |
원래 값이 변환 데이터형의 범위를 벗어날경우, 대개 하위 바이트들만 복사된다 |
■ 수식에서의 데이터형 변환
- 일반적으로 컴파일러는 산술식에 어떤ㅌ 데이터형 변환이 이루어져야하는지를 검사한다.
이를 위해 컴파일러가 검사하는 목록은 순서대로 다음과 같다.
ⓐ한쪽 피연산자가 long double형이면, 상대편 피연산자를 long double형으로 변환한다.
ⓑ그렇지않고 한쪽 피연산자가 double형이면, 상대편 피연산자를 double형으로 변환한다.
ⓒ그렇지않고 한쪽 피연산자가 float형이면, 상대편 피연산자를 float형으로 변환한다.
ⓓ그렇지않다면 피연산자들이 정수형이므로 정수승급이일어난다.
ⓔ이경우에, 한쪽 피연산자가 unsigned long형이면, 상대편 피연산자를 unsigned long형으로 변환한다.
ⓕ그렇지않고 한쪽 피연산자가 long int 형이고 상대편 피연산자가 unsigned int형이면, 두데이터형의 상대적인 크기에 따라 변환이
결정된다. long형이 unsigned int값을 나타낼수 있으면, unsigned int형이 long형으로 변환된다.
ⓖ그렇지않으면 두 피연산자가 모두 unsigned long 형으로 변환된다
ⓗ그렇지않고 한쪽 피연산자가 long형이면, 상대편 피연산자를 long형으로 변환한다.
ⓘ그렇지않고 한쪽 피연산자가 unsigned int형이면, 상대편 피연산자를 unsigned int 형으로 변환한다.
ⓙ컴파일러가 이 지점까지 도달한다면, 두 피연산자는 int형이다.
■데이터형 변환자
C++에서는 데이터형 변환자를 사용하여 강제로 데이터형을 변환시킬수있다.
데이터형 변환자는 두가지 형태로 사용된다.
long (thorn) //thorn의 long형 변환을 리턴한다.
데이터형 변환자는 thron변수 자체는 변경하지않는다.
그대신에 지시된 데이터 형의 새로운 값을 만든다.
typeName (value) // value를 typeName형으로 강제 변환한다.
두번째형태는 C++에서만 사용하는 형태이다.
이것은 내장 데이터형에 대한 데이터형 변환을 마치 사용자 정의 클래스를 위해 설계할 수 있는 데이터 형
변환처럼 보이게한다.
satic_cast<>연산자는 어떤 수치 데이터형을 다른 수치 데이터형으로 변환하는데 사용할수 있다.
예를 들어, 다음과 같이 thorn을 long형 값으로 변환하는 데 사용할수 있다.
일반적으로 다음과 같이 할수 있다.
======================================요약=============================================
C++의 기본 데이터형은 두그룹으로 나뉜다. 한 그룹은 정수형으로 저장되는값들로 이루어진다. 다른 한 그룹은 부동 소수점형으로
저장되는 값들로 이루어진다. 값을 저장하는데 사용되는 메모리 크기와 그것이 signed냐 unsigned냐에 따라 정수형은 다시 여러가지
형으로 세분된다. C++의 정수형을 크기가 작은것부터 순서대로 나열하면 bool,char,signed char,unsigned char, short , unsigned shore, int , unsigned int, long, unsigned long형의 순이다.
wchar_t라는 정수형이 하나더있다. 앞의 크기 순서에서 wchar_t가 들어갈 위치는 시스템에따라 다르다. char형은 그시스템의
기본문자세트에 속하는 어떠한 문자도 저장할수있을만큼 커야한다. wchar_t형은 시스템의 확장문자 세트에 속하는 어떠한 문자도
저장할수 있을만큼 커야한다. short형은 최소 16비트이다. int형은 최소한 short형만큼 커야한다. long형은 최소 32비트이고, 최소한 int형만큼 커야한다. 각 데이터형의 정확한 크기는 C++시스템에 따라 다르다.
문자들은 그에 해당하는 수치 코드로 나타낸다. 그수치코드를 문자로 해석할것인지 수로 해석할 것인지는 입출력(I/O) 시스템이
결정한다.
부동 소수점형은 소수부가 있는 값을 나타낼수 있다. 또한 정수보다 훨씬 큰값을 나타낼수있다. 부동소수점형은 float, double, long double형 세가지가 있다. long double형은 최소한 double형 만큼은 커야한다. double형은 최소한 float형만큼은 커야한다.
일반적으로 float형은 32비트, double형은 64비트, long double형은 80에서 128비트의 메모리를 사용한다.
C++는 크기가 다른 다양한 데이터형과, 그들의 signed,unsigned 변형까지 제공하므로 특정 데이터에 적합한 데이터형을 골라서
사용할수 있다.
C++는 수치 데이터형에 대해 산술 연산(덧셈, 뺄셈, 곱셈, 나눗셈, 나머지셈) 을 수행하는 연산자를 제공한다. 두 연산자가 하나의 피연산자에 걸려있을때에는 우선 순위 규칙과 결합 방향 규칙을 적용하여 어느 연ㅅ간을 먼저 수행할 것인지를 결정한다.
변수에 값을 대입할때, 수식에 서로 다른 데이터형을 혼합하여 사용할때, 데이터 형 변환자를 사용하여 강제로 데이터형을 변환
시킬때, 이러한 경우에 C++에서는 한 데이터형을 다른 데이터형으로 변환한다. 데이터형 변환에서 데이터의 실제값은 대부분 그대로
유지된다. 예를 들어, int형 값을 long형으로 변환하는 것은 전혀 문제를 일으키지 않는다. 그러나 부동 소수점형을 정수형으로
변환할때에는 약간의 주의가 필요하다.
다양한 데이터형 변환 규칙을 고려 해 볼때, C++의 기본 데이터 형이 이렇게 많을 필요가 있을까 의문이 들수도있다.
그러나 기본데이터형들 중의 어느 하나가 상황에 꼭 맞는 경우를 언젠가는 만나기때문에 그럴 걱정은 필요없다.
'C++ > C++ PRIMER PLUS' 카테고리의 다른 글
함수 - C++의 프로그래밍 모듈 (0) | 2011.11.09 |
---|---|
분기 명령문과 논리 연산자. (0) | 2011.11.07 |
루프와 관계 표현식 (0) | 2011.10.27 |
복합 데이터형 (0) | 2011.10.27 |
C++시작하기 (0) | 2011.10.18 |
설정
트랙백
댓글
글
main() 함수내의 기본구조
// | 주석문 |
#include | 전처리 지시자 |
int main() | 함수머리 |
using namespace | 지시지 |
{ } | 범위내에는 함수의 몸체 |
cout | 메시지를 출력하는 명령문 |
return | main()함수를 종료 |
●main()함수
--------------------------------------------------------------
int main()
{
명령문들
return 0;
}
첫번쨰행에 있는 int main()이라는 부분이 함수머리(function head)
중괄호 { } 로 묶여있는 부분이 몸체(function body)
- 함수머리는 프로그램을 다른 부분과 연결하는 고리역활, 함수몸체는 그함수가 처리하는 동작을 컴퓨터에게 지시.
컴퓨터에게 내리는 지시를 명령문이라 한다. C++에서 모든 명령문은 세미콜론(;)으로 끝나야 한다.
main() 함수의 끝에 있는 명령문은 return 명령문 - 함수를 종료하는 역활을 함.
함수머리는 호출함수와 피호출 함수의 인터페이스를 나타냄. 함수이름의 앞부분을 함수 리턴형이라한다. 이것은 피호출 함수가 호출함수로 다시 넘겨주는 정보의 흐름을 나타냄.
함수이름뒤에 있는 괄호부분의 안의 부분을 전달인자 리스트 또는 매겨변수리스트라고 함.
int main() 함수머리는
main()함수가 자신을 호출한 함수로 부터 어떠한 정보도 전달받지 않지만, 그함수에게 정수값을 리턴한다는것을 나타냄.
main() //클래식 C의 함수 머리 스타일
- 리턴형을 생략하는 것은 그함수가 INT형이라고 말하는것과 같다
C++ 에서는
int main(void) // 명시적인 스타일
-괄호안에 키워드 void를 사용하는 것은 그함수가 다른함수로부터 어떠한 정보도 전달받지않는다는 것을 명시적으로 밝힘.
C++에서 괄호안을 비워두는 것은 괄호안에 void 가 있는것과 같다.
void main()
-void리턴형이, 함수가 값을 리턴하지 않는다는것을 뜻함.
main()의 끝에 리턴명령어를 두어야함. 컴파일러가 리턴명령을 만나지 못한채 main()문의 끝에 도달한다면
main()문을 끝내는것과 동일한효과를 낸다.
return 0;
- 암시적 리턴은 다른함수들에는 해당되지않고 오로지 main()함수에만 특별히 허용된다.
■이름이 반드시 main()이어야하는 이유
C++프로그램에는 main()함수가 반드시 하나가 있어야함.(대/소문자가 틀리거나 철자가 틀리면안됨)
프로그램에 main()함수가 없으면 완전한 프로그램이 아님. 이러한경우 컴파일러에서 main()함수를 정의하지 않았다고 지적.
-예외도있음. Windows프로그래밍에 동적 링크 라이브러리(DLL)모듈을 작성할때. DLL모듈은 다른 Windows프로그램들이 사용할수 있는 코드 로서, 독립된 프로그램이 아니므로 main()이 필요없다.
일반적인 독립형 프로그램에튼 반드시 main()이 필요함.
■C++ 주석문
더블슬러쉬(//) 뒤에는 항상 주석문.
주석문은 프로그램안에 기록해두는 메모의 일종. 프로그램의 구역을 구분하거나 코드의 어떤부분이 어떤 역활을 하는것인지 표시하는데사용.
주석문에는 // 를 사용하여 한줄 주석을 할수도있고, /* (주석시작) */(주석의끝) 과같은 부호를 사용하여 원하는 만큼주석처리가능.
■전처리기와 iostream 파일
#include <iostream> //전처리 지시자
이지시자는 전처리기에 iostream 파일의 내용을 프로그램에 추가하라고 지시. 컴파일이 되기전에 원시코드에 텍스트를 추가하거나 텍스트를 대체 하는것이 전처리기가 수행하는 기본역활.
iostream 의 i는 (input) 입력 o 는 (out)출력 을 나타냄.
프로그램에서 cout과 cin의 기능을 사용할려면 iostream을 정의해야함.
■namespace
iostream.h대신에 iostream 을 사용할시에 프로그램이 iostream의 정의를 사용할수 있게 하려면 다음과 같은 이름공간지시자를사용.
using namespace std;
-using지시자라고함.
using 지시자는 std이름 공간에 들어있는 모든 이름을 사용할수 있게 해준다.
using std::cout;
using std::cin;
using std::endl;
매번 using std:: 를 쓰지 않기 위해선 using namespace std 지시자를 사용하면
std::를 붙이지않고 cin , cout을 사용가능.
■cout을 이용한 C++출력
cout<<"C++의 세계에 오십시오.";
큰따옴표안에 있는것은 출력할 메세지이다. c++에서 큰따옴표안에 들어있는 연속된 문자들을 문자열이라고한다.
<<표시는 명령문이 그문자열을 cout에 전달한다는 것을 뜻함. <<표시가 나타내는 방향이 정보의 흐름을 상징.
cout은 문자열(string),수(number),문자(character)들을 포함한 여러가지 다양한 정보를 출력하는 방법을 알고 있는 미리정의된 객체이다.
■조정자 endl
cout<<endl;
endl은 새로운 행이 시작된다는 중요한 개념을 나타내는 특별한 C++표기이다. endl을 출력 스트림에 삽입하면 화면 커서가 다음행의 시작위치로 간다. cout에게 특수한 의미를 가지는 endl과 같은 특별한 표기들을 조정자(manipulator)라고 부른다.
cout과 마찬가지로,endl도 iostream 헤더파일에 정의되어있고, std 이름공간에 속한다.
cout은 문자열을 출력하고 나서 다음행의 시작위치로 커서를 자동으로 넘겨주지 않는다. 그러므로 넘겨주기 위해서는 cout을 사용한다.
■개행문자(\n)
c표기 방법은 \n 은 개행문자(newline character)라고 부르는 하나의 문자를 나타내는것으로 간주된다.
문자열을 출력하고자 할떄, 꼬리표처럼 뒤에 endl을 매다는것보다 문자열의 일부로 개행 문자를 포함시키는 것이 타이핑의 수고가 적기 때문에 사용한다. 개행문자는 "이스케이프 시퀀스"라고 하는 특별한 키스트로크결합의 한예이다.
■토큰과 화이트스페이스
한행의 코드에서 더이상 분리할수 없는 기본요소를 "토큰" 이라고 한다.
일반적으로 하나의 토큰은 빈칸,탭,캐리지 리턴 에 의하여 다음 토큰과 분리된다. 빈칸, 탭, 캐리지 리턴을 집합적으로
화이트스페이스 라고 부른다. 괄호나 콤마와 같은 일부 단일 문자들은 화이트 스페이스로 분리하지 않아도 되는 토큰이다.
■C++원시 코드 스타일
●한행에 하나의 명령문을 사용한다.
●함수를 여는 중괄호 { 와 닫는 중괄호 } 에 각각 한행을 할애한다.
●함수안에 들어갈 명령문들은 중괄호에서 약간 오른쪽으로 들어간 위치에서 시작한다.
●함수 이름과 괄호 사이에는 어떠한 화이트 스페이스도 넣지않는다.
■C++명령문
-변수를 선언하는 선언명령문, 변수에 값을 대입하는 명령문
carrots =25; // 변수에 값을대입
●선언명령문과 변수
int carrots;
-이명령문은 하나의 정수를 저장할수 있는 한 기억공간을 할당하고, 그위치가 어딘지 말해주는 꼬리표를 붙이는 작업을 수행.
int : 소수부가 없는 정수형을 말하며 양의 정수와 음의 정수가 있다. int형의 크기는 사용하는 시스템에따라 다르다.
선언명령문은 데이터형을 선언하는것뿐만아니라, 앞으로 프로그램에서 그기억공간에 저장되어있는 값을 carrots라는 이름으로 사용하겠다고 선언하는것이다.
이와같은 carrots를 변수(variable)라고 부른다. 변수라는 이름은 값이 변하기때문에 붙여진 이름이다.
int carrots ;←세미콜론은 명령문의 끝을 나타냄.
↑ ↑
| 변수이름.
저장될데이터형.
선언명령문을 정의 선언 명령문, 또는 정의라고 부른다. 정의가있으면 컴파일러는 그변수를 위해 메모리공간을 할당한다.
■C++의 기타 명령문
●cin 사용법
입력은 바깥 세상에서 프로그램 안으로 흘러들어가는 문자들의 스트림이다. cin은 iostream 파일에 입력스트림을 나타내는 객체로정의되어있다. 출력을 할때는 cout이 <<연산자를 사용하여 문자들을 출력스트림에 삽입하고 , 입력할때는 cin이 >>연산자를 사용하여 입력스트림에서 문자들을 가져온다.
가져온 정보를 저장할 변수는 >> 연산자의 오른쪽에 적는다.
■함수
C++함수는 두가지 유형이있다. 리턴값이있는것과 리턴값이 없는 것.
표준라이브러리에 있는 함수를 사용할수도있고, 사용자가 직접만들어서 사용할수도있다.
●리턴값이있는함수.
-리턴값이있는 함수는 변수에 대입할수있는 하나의 값을 만들어낸다.예를들어 C/C++표준라이브러리에는 어떤 수의 제곱근을
리턴 하는 sqrt()라는 함수가있다. 제곱근을 구하여 변수 x에대입하여야한다고 가정할때, 다음과 같은 코드가 작성된다.
괄호안에있는값은 함수에 전달되는 정보이다
x= sqrt(6.25) --->피함수호출 sqrt()코드 -> x에 값을 리턴한다.
x= sqrt(6.25);
↑ ↑ ↑_함수에 전달되는인자
| 함수이름
함수 리턴값이 x에 대입된다.
-전달인자는 함수에 전달되는 정보이고, 리턴값은 함수가 돌려주는값이다.
다만, 함수를 사용하기전에 C++컴파일러는 그함수가 어떤 종류의 전달인자를 사용할것이며, 어떤 종류의 리턴값을 리턴하는지 미리 알고 있어야한다. 즉, 리턴값이 정수인지, 문자인지,소수부가있는수인지 알고있어야한다는것이다. 이런정보가 없다면 컴파일러는 그리턴값을 어떻게 처리할지 판단할수가없다.
C++은 함수원형 명령문을 사용하여 이런 정보를 컴파일러에게 전달한다.
C++라이브러리에는 sqrt()함수가 소수부가 있는수 를 전달인자로 전달받으며, 전달받은것과 동일한 데이터형의 값을 리턴한다고 정의 되어있다.
소수부가 있는 실수는 double형으로 나타내며, sqrt()의 함수 원형은 다음과 같다.
double sqrt(double); //함수원형
앞에있는 double는 sqrt()함수가 double형의 값을 리턴한다는뜻.
뒤에있는 double는 sqrt()함수가 double형의 전달인자를 전달받는다는뜻이다.
sqrt()함수를 사용하려면 함수원형을 제공해야하는데 함수원형을 제공하는 방법은 두가지가있다.
●함수 원형을 원시코드 파일에 직접 입력한다.
●함수원형이 들어있는cmath헤더 파일을 포함시킨다.
■변이함수
어떤함수는 하나이상의 정보를 요구한다. 그러한 함수는 여러개의 전달인자를 콤마(,)로 구부한다. pow()는 전달인자를 2개요구한다.
이함수는 첫번째 전달인자를 두번째 전달인자의 횟수만큼 거듭제곱하여 그결과값을 리턴한다.
double pow(double, double); //2개의 전달인자를 가진 함수 원형
예를들어 5의 8제곱근을 구한다면
double pow(5.0,8.0); //전달인자 리스트가 있는 함수호출.
전달인자를 사용하지않는 함수도있다. C라이브러리에는 전달인자는 사용하지않지만 임의의 정수를 리턴하는 rand()라는 함수가있다.
이함수의 원형은
int rand(void); //전달인자가 없는 함수원형.
키워드 void는 전달인자를 사용하지않는다는것을 명시적으로 밝히는것이다.
■함수의 모양
함수정의의 모양을 다음과 같이 일반화 가능.
{
statements
}
=====================================================================================================================
※요약
C++프로그램은 함수라고 부르는 하나또는 그이상의 모듈들로 이루어진다.
프로그램은 main()이라는 함수부터 실행이 된다. 그러므로 어떤 프로그램이든지간에 main()함수가 반드시 하나 있어야한다.
함수는 함수머리와 함수몸체로 이루어진다. 함수 머리는 그함수가(리턴값이 있는경우) 어떤 데이터형의 값을 리턴하고, 어떤 종류의 정보를 전달인자로 받는지 나타낸다. 함수몸체는 중괄호{ }로 둘러싸인 C++명령문들로 이루어진다.
C++명령문들의 유형은 다음과같다.
●선언명령문: 함수에 사용되는 변수의 이름과 데이터형을 선언한다.
●대입명령문: 대입연산자(=)를 사용하여 변수에 값을 대입한다.
●메시지명령문: 객체에 메시지를 전달하여 활동을 시작하게한다.
●함수호출: 함수를 동작시킨다. 피호출 함수가 종료되면, 프로그램은 호출 함수의 함수 호출 바로 뒤에 있는 명령문으로 복귀한다.
●함수의 원형: 함수가 기대하는 전달인자의 개수, 전달인자의 데이터형, 함수의 리턴형을 선언한다.
●return 명령문: 피호출 함수가 리턴하는 값을 호출 함수에 전달한다.
클래스는 사용자가 정의하는 데이터 형식이다. 클래스에는 정보를 어떻게 표현할것이며, 그정보를 대상으로 수행할수 있는 동작은 무엇인지가 함께 정의 된다. 데이터형을 사용하여 간단한 변수를 생성하는것과 마찬가지로, 객체는 클래스의 속성을 사용하여 실제로 생성하는 구체물이다.
C++에서는 입력과 출력을 위해 cin과 cout이라는 두개의 미리정의된 객체를 사용한다. 이들은 각각 istream과 ostream클래스의속성
으로 생성된 객체이다. istream과 ostream 클래스는 iostream파일에 정의되어있다. 이클래스들은 입력과 출력을 연속된 문자들의 스트림이라고 간주한다. 삽입 연산자(<<)는 ostream 클래스에 정의되어있으며, 데이터를 출력 스트림에 삽입한다. 추출 연산자(>>)
는 istream 클래스에 정의되어있으며 스트림으로 부터 정보를 추출한다. cin과 cout은 잘짜여진 영리한 객체이기때문에 프로그램의 문맥에 따라 한 형식을 다른 형식으로 자동변환할수 있다.
C++는 방대한 양의 C라이브러리 함수를 사용할수 있다. 라이브러리 함수를 사용 하려면 함수 원형을 제공하는 헤더파일을 프로그램에포함시켜야한다.
'C++ > C++ PRIMER PLUS' 카테고리의 다른 글
함수 - C++의 프로그래밍 모듈 (0) | 2011.11.09 |
---|---|
분기 명령문과 논리 연산자. (0) | 2011.11.07 |
루프와 관계 표현식 (0) | 2011.10.27 |
복합 데이터형 (0) | 2011.10.27 |
데이터처리 (0) | 2011.10.20 |
설정
트랙백
댓글
글
키보드 관련 대표적인 메세지는 WM_KEYDOWN과 WM_KEYUP
특정키를 계속 누르고 있으면 WM_KEYDOWN 메세지가 계속 발생함.
메세지를 전달할떄는 어떤키를 눌렀는지에 대한 파라미터가 담겨있음.
키보드 메세지는 모든키에 발생하지만 예외가 있음.
예외) Alt 키 와 F10키
두키를 누르면 WM_KEYDOWN 메세지가 발생하지 않고 WM_SYSKEYDOWN 메세지가 발생함, 그리고 이메세지와 WM_SYSKEYUP 메세지가 짝을이룸.
WM_KEYDOWN 메시지의 파라미터에 ASCII코드의 문자에 해당하는 키가 입력될경우,
메세지 루프의 TranslateMessage()함수가 WM_KEYDOWN 메시지를 다시 WM_CHAR 메시지로 전환하여 전송함.
<소스 코드 5-03>==================================
void CKeyMoveView::OnKeyDown(UNIT nChar, UINT nRepCnt, UINT nFlags)
{
CPoint ptChild; //차일드 윈도우의 좌표.
CPoint Rect; //차일드 윈도우의 좌표및 크기.
m_wndChild.GetWindowRect(&Rect);//차일드 윈도우의 두 좌표 정보(스크린 기준)를 가져온다.
ptChild.x = Rect.left;
ptChild.y = Rect.top
ScreenToClient(&ptChild); // 스크린 기준 좌표를 클라이언트 뷰 기준의 좌표로 변환.
switch(nChar)
{
case VK_LEFT: //방향키 왼쪽이 눌러지면..
ptChild.x -=10;// 10픽셀만큼 x좌표 값 에서 감소.
break;
case VK_RIGHT: // 방향키 오른쪽이 눌러지면
ptChild.x +=10;// 10픽셀만큼 x좌표 값 에서 증가.
break;
}
m_wndChild.SetWindowPos(&CWnd::wndTop,ptChild.x,ptChild.y,0,0,
SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOSIZE);
CView::OnKeyDown(nChar,nRepCnt,nFlags);
}
======================================================
윈도우 좌표계와 활용함수(GetWindowRect(),SetWindowsPos())를 이해하고,
CPoint나 CRect 같은 데이터 클래스에 대해서도 알아야한다.
<소스코드 5-04>======================================
/*
* Virtual Keys, Standard Set
*/
#define VK_LBUTTON 0X01
#define VK_RBUTTON 0X02
#define VK_CANCLE 0X03
#define VK_MBUTTON 0X04
#if(_WIN32_WINNT >= 0X0500)
#define VK_XBUTTON1 0X05
#define VK_XBUTTON2 0X06
#endif /* _WIN32_WINNT >= 0X0500 */
=====================================================
OnKeyDown() 메시지 핸들러 함수의 첫번째 인자인
nChar에는 어떤키를 눌렀는지에 대한 정보가 들어있다.
이런값을 가상 키값(Virtual Key Code)이라 하며, WinUser.h파일에 정의되어있다.
ESC 키의 경우 VK_ESCAPE이며, ENTER 경우 VK_RETURN.
윈도우에서는 알파벳이나 숫자처럼 사람이 인식하는 문자열과 관련된 키에 의한 발생한 WM_KEYDOWN메시지는 WM_CHAR 메시지로 전환하여 재전송하게됨.
이런 작업은 메시지 루프에서 TranslateMessage() 함수가 처리.
그러므로 문자열 입력을 처리하고 싶다면 WM_CHAR메시지 핸들러를 등록하는 것이 바람직함.
nRepCnt인자는 반복횟수를 의미.(대부분의 횟수는 1)// 키를 계속누르고 있으면, 2나 3이 될수도있고 그이상이 될수도음.
nFlags 인자는 키보드에 대한 상세한 상태 정보를 담고있음.(비트 단위로 잘라서 특정 범위값을 살펴 봐야함.)
VK_RIGHT 는 오른쪽 화살표를 눌렀을때도 해당하지만 키패드에서 Number Lock 을 끈상태에서는 숫자 6을 눌렀을때에도해당함. 만일 둘을 구별해야한다면 nFlags에서 특정 비트의 값을 확인하여 판별가능.
스캔코드의 값은 모두 같아 보이지만 확장키의 비트값이 차이가있음. 그리고 방향키를 누르더라도 여러키(Ctrl + Alt)를 조합하면 차이가 생김.
<그림 5-1>참조 !!!!!.
0~7 : 스캔코드(키보드의 특정키를 식별하는 값.)
8 : 확장키(1이면 확장키)
9~10 : 사용하지않음.
11~12: 윈도우 OS에서 사용
13 : 비트컨텍스트(1이면 Alt키가 눌러진상태)
14 : nChar값에해당키 (0이면 키가 눌린상태) ▶WM_KEYDOWN 메시지는 키를 눌렀을때 발생하기 때문에.
15 : 비트 전송 코드 (0이면 키를 누른상태 WM_KEYDOWN 메시지의 특성상 이값이 0임)
nFlag 값의 변화를 확인하고 싶다면 OnKeyDonw() 메시지 핸들러 함수에 중단점을 설정(F9) 디버그 모드로 실행(F5)
CPoint와 CRect 같은 클래스들은 각각 POINT 와 RECT 구조체를 클래스화 하고 연산자를 정의한것.
CPoint 클래스의 가장중요한 맴버함수는 x,y
CRect 클래스의 중요맴버함수는 left, right, top, bottom
그리고 가장 많이 사용하는 메소드로는 Width() 와 Height() 등이있음.
GetWindowRect() 함수는 CWnd클래스의 맴버이며, 모니터기준 왼쪽 위와 오른쪽아래의 좌표를 알아내는 함수.
Rect구조체에 m_wndChild 윈도우를 모니터 기준 좌표로 반환.
왼쪽위좌표를 CPoint 클래스에 저장. 이좌표를 변환하여 현재위치를 파악하고 눌러진 키보드가 무엇인지 확인하여 새로운 위치로 윈도우를 이동시킴.
ScreenToClient() 함수는 CWnd 클래스의 맴버함수이며, POINT 구조체로 전달받은 좌표를 특정윈도우 기준 좌표로 변환.
<그림 5-3> 기준으로 GetWindowRect() 함수로 얻은 왼쪽위의 좌표(C)는 (300,250)이 되고, ScreenToClient()함수를 호출
하여 클라이언트 뷰 기준으로 변환 하면 (100,100) 이됨.
SetWindowPos()함수는 윈도우의 위치, 크기,Z-order를 변경하는 함수. 원형은
===========<SetWindowPos()>================
BOOL SetWindowsPos(
const CWnd *pWndInsertAfter,
int x, int y,
int cx, int cy,
UINT nFlags
);
=======================================
pWndInsertAfter 인자는 함수를 호출한후 윈도우의 Z-order 를 어떻게 할것인지 명시.
※Z-order란 두윈도우가 겹쳤을때 어떤것이 아래이고 어떤것이 위인지 결정하는값.
SWP_NOZORDER로 주면 NULL값, 앞과같이 이런 플래그를 설정하지 않았다면 값은 NULL이 될수 없으며 CWnd 클래스의 스태틱 맴버중에 하나의 값으로 설정되어야한다,]
=========== CWnd클래스 스태틱 맴버 ===========
static AFX_DATA const CWnd wndTop;
static AFX_DATA const CWnd wndBottoml;
static AFX_DATA const CWnd wndTopMost;
static AFX_DATA const CWnd wndNoTopMost;
BOOL SetWindowPos(const CWnd * pWndInsertAfter, int x, int y,
int cx, int cy, UINT nFlags);
(SetWindowPos() ▶ Z-order)
=================================================
Z-order | 의 미
-----------------------------------------------------------------------------------------
WndBottom | Z-order를 최하위로 합니다.
------------------------------------------------------------------------------------------
WndTop |Z-order를 최상위로 합니다.
-------------------------------------------------------------------------------------------
WndTopMost |Z-order를 최상위로 하고 시스템 윈도우 속성을 갖습니다.
--------------------------------------------------------------------------------------------
WndNoTopMost | 일반윈도우 중 최상위 윈도우가 되도록합니다.
====================================================
=========================================================
x,y 인자는 새로 설정할 윈도우의 왼쪽 위 좌표.
예제에서는 이값을 변경하여 윈도우의 위치를 변경. 만일 SWP_NOMOVE 플래그로 설정하면 두인자는 무시.
cx, cy인자는 새로설정할 윈도우의 폭과 높이. 예제에서는 SWP_NOSIZE로 설정되어있어 값은 0(윈도우크기변경X)
======================nFlags===============
SWP_HIDEWINDOW | 윈도우가 화면에서 사라지도록 함.
-------------------------------------------------------------------------
SWP_SHOWWINDOW | 윈도우가 화면에 보이도록 함.
------------------------------------------------------------------------
SWP_NOACTIVATE | 윈도우를 활성하지 않음.
-----------------------------------------------------------
SWP_NOMOVE | 윈도우의 위치를 변경하지않음(x,y값무시)
----------------------------------------------------------
SWP_NOREDRAW | 윈도우를 다시그리지 않음.
-----------------------------------------------------------
SWP_NOSIZE | 윈도우의 크기를 변경하지않음.(cx, cy값 무시)
-----------------------------------------------------------
SWP_NOZORDER | 윈도우의 Z-order 를 변경하지 않습니다 (pWndInsertAfter 무시)
==============================================
-WM_KEYDOWN 메세지에서 모든것을 처리한다면 OnKeyDown()함수가 길이가 너무 커질수 있으므로, WM_CHAR메세지 핸들러를 추가 하여 특수키입력과 문자키 입력을 구분하여 처리할것!
=========<소스코드 5-08>====================================
void CKeyMoveView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CString strText = TEXT(" "); // 문자열을 선언하고 빈문자열로 초기화
strText.Format(TEXT("%c"),nChar);
//입력한 키가 Enter, Back, ESC키가 아니면
//해당 ASCII문자로 차일드 윈도우 텍스트를 변경한다.
if(nChar != VK_RETURN && nChar != VK_BACK && nChar !=VK_ESCAPE)
{
m_wndChild.SetWindowText(strText);
}
CView::onChar(nChar, nRepCnt,nFlags);
}
===============================================================
nChar인자값이 Enter,BackSpace,ESC 키인지 검사를 하면 WM_CHAR메세지가 발생.
예제에서는 문자를 출력하려고 시도하지만, 당연히 제대로 된 ASCII코드가될수없음.
그래서 세가지 키입력에 대해서는 예외처리.
OnChar() 함수의 nChar(어떤키가 눌렀는지) 와 nRepCnt(몇회눌러졌는지) 인자는 OnKeyDown()함수와 같지만
nFlags인자는 다름 32bit를 사용하고 있으며, 의미가 있는 비트의 위치가 다름.
CString코드의 장점
ⓐ유니코드 문자열을 처리하고 일반 멀티 바이트 문자열을 처리하는 코드나 함수를 따로 분리하지 않아 처리가 훨씬
간단함.
ⓑ더하기 연산자나 할당연산자가 정의 되어있음.
ⓒ문자열 처리에 필요한 메모리를 알아서 관리 하기떄문에 메모리를 할당/해제 하는 코드를 작성할 필요가 없음.
SetWindowText() 함수는 CWnd 클래스의 맴버함수.
인자로 전달받은 문자열로 윈도우의 텍스트를 변경. 이와 쌍을 이루는 함수로 GetWindowText()함수도 있음.
윈도우 운영체제에서는 Alt 키나 F10 키를 누르면 메인 메뉴포커스로 이동.
이 두키에 대한 입력이 발생하면 WM_KEYDOWN과 WM_KEYUP 메시지가 아니라 WM_SYSTEMDOWN과 WM_SYSKEYUP
메시지가 발생함.
============<소스코드 5-09>=============================
void CKeyMoveView::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CString strMessage =TEXT("");//메시지를 저장할 문자열 객체.
//Space 키에 대한 상태 정보를 수집
WORD wResult = ::GetKeyState(VK_SPACE);
BYTE byHigh = HIBYTE(wResult);
//상위 바이트 의 1번 비트가 1이면 키가 눌러진 상태
if(byHigh & 0x01)
{
strMessage += TEXT("Alt+Space,");
//같은 방법으로 Caps Locks 키 상태를 검사
wResult = ::GetKeyState(VK_CAPITAL); // :: API에서 함수를 찾음.
//하위 바이트의 1번 비트가 1이면 토글 키가 켜진상태
BYTE byLow =LOBYTE(wResult);
if(byLow & 0x01)strMessage += TEXT("CAPS LOCK ON");
else strMessage += TEXT("CAPS LOCK OFF");
AfxMessageBox(strMessage);
}
CView ::OnSysKeyDown(nChar, nRepCnt, nFlags);
}
=========================================================
OnSysKeyDown() 함수의 인자는 OnKeyDown() 함수와 같습니다.
OnSysKeyDown()함수는 Alt키와 조합된 키입력에 대한 호출. 지금의 코드에서는 ::GetKeyState() API 함수를 이용하여
특정키의 상태를 검사하고 Alt키와 조합됬는지 확인.
==========================GetKeyState()함수의원형==============
SHORT GetKeyState(
int nVirtKey // vitual -key code
);
=========================================================
인자로는 상태를 검사할 키의 가상키값을 받습니다.
WORD wResult = ::GetKeyState(VK_SPACE); 은 VK_SPACE의 상태를 확인하여 wResult라는 16비트 맴버변수에 결과를 저장하고 있음.
SHORT형이나 WORD형이나 모두 16비트의 크기를 갖음. 그리고 저장된 값이 얼마인지 단순히 확인하는것이아니라,
다시 상위바이트(8비트)와 하위 바이트로쪼개서 키의 상태를 확인함.
HIBYTE()와LOBYTE() 매크로는 인자로 주어진 16비트 값에서 각각 상위, 하위 바이트로 잘라내는 매크로.
GetKeyState()함수가 반환하는 값의 상위 바이트는 키를 누른상태인지에 대한 정보가 들어있고,
하위 바이트에는 토글에 대한 정보가 들어있음.
VK_SPACE는 토글키가 아니므로 굳이 하위정보를 확인할필요없음.
키를 눌렀는지 검사하려고 값을 비교하는 것이 아니라 1번 비트가 1인지 비트 연산(&)하여 확인 합니다.
CapsLocks, NumberLock, ScrollLock 키는 대표적인 토글키.
한번씩 누를때마다 상태가 On/Off되는 특성이있음. 이런정보는 GetKeyState()함수가 반환한 결과의 하위바이트에 들어있습니다.
On/Off상태는 앞서와같이 1번비트를 확인 하면됨.
CString 클래스의 '+='연산자를 이용하여 문자열을 합침.(C언어에서의 strcat()함수와 동일결과)
WM_SYSCHAR메시지는 TranslateMessage()함수가 생성. WM_CHAR 메시지는 문자키 입력일떄 발생하지만 WM_SYSCHAR메시지는 Alt키와 문자키 입력이 조합된경우에만 발생(ex. Alt+S)
'WindowPrograms > MFC' 카테고리의 다른 글
8. 비트맵과 이미지처리 (0) | 2011.10.24 |
---|---|
MFC1장 (0) | 2011.10.12 |
MFC3장 -MFC코드의 기본구조 (0) | 2011.10.12 |
설정
트랙백
댓글
글
* WinMain 함수
- C언어의 메인과 마찬가지임..
시작되는 함수는 여기에서 처리함
핵심함수: _tWinMain
MyRegister(hInstance);
InitInstance
★main message loop(가장중요)//메시지 루프
while(GetMessage(&msg,NULL,0,0))
{
if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Get Message <- Msg Queue 에서 가지고옴
메시지를 가져오면 루프를 돌고 메시지를 가지고 오지못하면(quit) 종료되는구조.
윈도우에서 Message란?
-모든것이 다 Message다.(보여지는것,생성되는것,이동되는것,입력 등등...)
-Message Driven 방식
H.I.D(Human Input Device)- Keyboard, Mouse등(H/W Event 발생)▶OS에서 감지
-키보드에서 키가 눌리면 하드웨어 이벤트가 발생하고, 이이벤트는 OS에서 감지하며 모니터(출력)에 Message로 보내줌.
-DispatchMessage 함수가 호출이 된다면 윈도우 프로시저 함수를 호출(Window Proc)<_Winproc->윈도우창의 인풋에 대해 메시지를 처리함.
메시지 내용은 (HWND hWnd,UNIT message, WPARAM wParam, LPARAM lParam)에 메시지정보를 담고있음.
작업관리자에서 "응답없음"이뜨는것은 메인메시지 에서 루프가 멈추면 "응답없음"발생
Handle 이란 -어떤 포인터에 관한 값.
-------------------------------tWinMain--------------------------
_tWinMain(HINSTANCE hInstance,) ▶응용프로그램 자체를 식별하는 값(실행파일의 메모리상의 위치)
lpCmdLine ▶ 프로그램시작할때 ~~~.exe /?라던지 실행할때쓰는것
nCmdShow ▶ 윈도우를 화면에 보여줄것인지 말것인지를 지정하는 값.
MSG msg ▶메시지 구조체.
====================================
typedef struct tagMSG{
HWND hwnd; //윈도우핸들.(특정윈도우를 식별할때 핸들로 식별함)▶값
UINT message;//핸들의 UINT형의 message로 전달됨
WPARAM wParam;- 메시지 파라미터(매개변수,인수,인자)
LPARAM lParam;- 메시지 파라미터(매개변수,인수,인자)
DWORD time;- 메시지가 전달된 시간(시스템시간)
POINT pt;-포인터 구조체 (x,y) 모니터상의 표시좌표 ↓y →x
#ifdef _MAC
DWORD lPrivate;
#endif
}MSG, *PMSG,NEAR *NPMSG,FAR *LPMSG;
===================================
HACCEL hAccelTable ▶단축키 테이블
<리소스뷰 ▶ HellowWorld▶HelloWorld.rc▶Acceletator▶IDC_HELLOWORLD(단축키테이블)
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING)
▶IDS_APP_TITLE - 선언부에 가면 그냥 값이들어가있고, 이값을 로딩을해서 전역변수로 선언되어있는 szTitle(TCHAR타입 MAX_LOADSTRING(100개-define) 선언)
▶ 리소스 뷰에서 String Table 안에 보면 IDS_APP_TITLE를 값으로 따지면 103번 그것을 로딩하면 HelloWorld값이 버퍼에저장
:다국어 지원때문에 리소스이름으로 넣어둠.
MyRegisterClass(hInstance)▶윈도우의 RegisterClassEx를 호출하는것이 목적.Class▶등급 c++의 클래스 뜻이아님.
윈도우 스탈일, 레지스터, 아이콘,마우스포인터,배경색,메뉴,윈도우이름-리소스뷰(IDC_HELLOWORLD(icon/Menu)
wcex.lpfnWndProcWinProc등록되었다는것은▶ Msg-OS-메세지큐-처리(WinProc)<호출하지는않음>-수동적으로 OS에의해 호출되어짐
UINT▶unsigned int
CALLBACK▶Call Convention(함수호출 시 스텍에 저장할때 어떻게 넣을꺼냐는것)<_stdcall>
WM_COMMAND: ▶ 어떤키를 눌렀을때 발생한 메세지를 처리
InitInstance(hInstance, nCmdShow)▶ CreateWindow함수를 직접 호출
===========================================================
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL,NULL, hInstance,NULL)
===========================================================
CreateWindow▶윈도우 핸들을 리턴
WS_OVERLAPPEDWINDOW▶ WS: 윈도우 스타일 OVERLAPPEDWINDOW:중첩해서 쓰는 윈도우(가장기본적인윈도우)
WM_PAINT▶윈도우를 다시 그릴때 사용
WM_DESTORY▶ 종료를 눌렀을때 불림.
'WindowPrograms > MFC' 카테고리의 다른 글
8. 비트맵과 이미지처리 (0) | 2011.10.24 |
---|---|
MFC 5장 키보드 입력 (0) | 2011.10.12 |
MFC3장 -MFC코드의 기본구조 (0) | 2011.10.12 |
설정
트랙백
댓글
글
응용프로그램도 포함되어있음. -> App + 문서 (Doc)
CWinApp 클래스
m_hInstance ▶현재 응용 프로그램의 인스턴스 핸들입니다. WinMain()함수의 첫번째 파라미터인 hInstance와 같은것임.
m_lpCmdLine ▶WinMain() 함수의 lpCmdLine 파라미터와 같은것입니다. 프로그램을 실행하였을때 명령줄 정보가 들어있음.
m_nCmdShow ▶WinMain()함수의 마지막 파라미터인 nCmdShow와 같은것.
m_pActiveWnd ▶응용프로그램의 최상위 프레임 윈도우에 대한 포인터. SDI구조에서 이값은 CMainFrame 클래스 객체의 포인터.
m_pszAppName ▶응용프로그램의 제목에 해당하는 문자열 포인터. 문자열의 좀더 정확한 정보는 문자열 테이블에 있는 AFX_IDS_APP_TITLE에 해당하는값
m_pszExeName ▶빌드한 실행 파일에서 확장자(.exe)를 제외한 파일명.
가상함수로 정의된 함수중 중요한것!
(InitInstance(), ExitInstance(),Run())
InitInstance()▶메서드는 응용프로그램이 초기화 되는 시점에서 호출되며 Run()메소드와 달리 대부분 재정의 되어있으며, 직접 코드를 수정할수 있다.
↓
Run()▶메시지 루프가 시작되는 시점에 CWinApp클래스의 Run()메소드가 호출되는 시점. Run()메서드가 반환하면 응용프로그램은 종료됨.
↓
ExitInstance()▶InitInstance()메소드와 반대로 응용프로그램을 종료하는 시점에 호출. 메인메시지 루프를 종료하는 시점(Run()함수가 반환한 시점) 에 호출. 기본적으로 재정의되어있지않지만
필요한경우 재정의해서 사용가능.
CframeWnd클래스 계층구도
CObject
└→CCmdTarget
└→CWnd
└→CFrameWnd
CFreameWnd& Control bar windows
1-2캡쳐
CDocument클래스 계층구도
Cobject
└→ CCmdTarget
└→ CDocument
메모장 처럼 한프로그램당 한개의 화면이므로, SDI(싱글도큐먼트)
OnNewDocument() ▶처음시작 할때 불림.(파일을 새로열때.)
AfxMessageBox() ▶Afx - MFC에서 제공하는 전역변수(팝업용 텍스트)
OnOpenDocument()▶문서열기 를 할시에 콜됨.
SetModifiedFlag(True)▶ 무조건 수정된걸로 인식되어 종료시에 저장을 물음.
MessageMap
-------------------------------------------------
BEGIN_MESSAGE MAP(CHelloSdiViewmCEditView)
~~
~~
~~
END_MESSAGE_MAP()
=================================================
속성으로 WM_CREATE()를 추가하면, 코드도 추가 됨과 동시에 MESSAGE_MAP에도 추가한 코드의 구조체가 추가된다.
WM_CREATE()추가시
-----------------------------------------
BEGIN_MESSAGE MAP(CHelloSdiViewmCEditView)
~~
~~
~~
ON_WM_CREATE()
END_MESSAGE_MAP()
------------------------------------------
MESSAGE_MAP 은 API의 case문을 대체 함.
'WindowPrograms > MFC' 카테고리의 다른 글
8. 비트맵과 이미지처리 (0) | 2011.10.24 |
---|---|
MFC 5장 키보드 입력 (0) | 2011.10.12 |
MFC1장 (0) | 2011.10.12 |
설정
트랙백
댓글
글
Point 란 번지. 포인터변수란 포인터를 저장할수 있는 변수 = 메모리의 특정위치를 저장
int *imsip; 의 정의는 imsip에 번지를 저장할수 있다는 뜻.
&연산자가 특정변수의 선두번지를 뜻한다면, *연산자는 그반대.
포인터변수에 저장된 선두번지를 참조하여 하나의값을 취함.
*imsip =1000; //imsip가 가르키는곳에 1000을 대입.
└→ imsip가 가르키는곳이 정확히 명시되어야함.
-Point는 형구별없이 무조건 4byte!
설정
트랙백
댓글
글
1. 객체지향의 개념
- 어떤문제를 해결하기 위한 과정을 순차적으로 설계하는것 ▶절차적 방법론
절차적언어: Pascal , Fortran, C, C++등..
2. 객체 클래스와 상속
- 유사한 특징을 지닌 객체를 묶어서 그룹지은것이 객체클래스(Object Class)
- 인스턴시에이션(Instantiation): 추상적 개념으로 부터 구체적 실례 하나를 만드는것.
- 같은 클래스에 속한 모든 객체는 동일한 메세지에 대하여 동일하게 반응함. 즉,동일한 메소드를 사용.
- 클래스를 바라보면 클래스간의 계층구조가 존재하는것을 알수 있음. 즉,어떤 클레스(Child Class,
sub Class, Derived Class)는 더높은 일반적인클래스(Parent Class, Super Class, Base Class)에
속하고, 그 클래스는 다시 더높고 포괄적인 클래스에 속한다.
- 객체지향 언어에서 클래스간 계층구조를 선언하는것은 상위클래스의 속성(Attribute)을
상속(Inheritance) 받기위함.
객체지향 설계과정 | |
1단계 | 문제를 풀기위해 필요한 객체설정 |
2단계 | 객체간의 유사한 속성파악 |
3단계 | 유사한 속성을 지닌객체를 모아 기본클래스 선언 |
4단계 | 기본 클래스로부터 특수한 속성을 지닌 하위 클래스 정의 |
- 상위 클래스에서 메소드를 선언하였을때, 어떤 클래스가 그하위 클래스라고 선언하기만 하면 자동으로
상위메소드를 상속받게된다. 자신의 소속을 밝힘으로써, 자신이 속한 단체의 재산 을 가져오는 행위.
3. C++객체지향
-프로그램의 단위성(Modularity)이 높음.
-큰문제 전체를 하나로 놓고 한꺼번에 모든 세부사항을 처리하는것보다 그문제를 잘라서
작은단위(Module)로 분할한 다음 이들을 개별, 단위별로 구현하는것이 훨씬 수훨한방법이다.
-객체단위로 잘라놓으면 나중에 다른문제를 해결할때에도 필요한 객체만 가져다가 조합함으로써
재사용성(Reusablity)을 높일수 있다.
①인터페이스 파일
-클래스의 선언은 Public 섹션과 Private색션 두부분으로 구성.
Public은 '공유'라는뜻으로, 내부에서 선언된 메세지를 외부사용자가 공유할수 있다는 의미이다.
따라서, 외부사용자는 여기에서 선언된 메세지를 사용하여, 이클래스의 객체에게 일을 시킬수 있다.
-객체지향 개념에서의 메세지를 C++에서는 맴버함수라고 부른다.
클래스 선언은 인터페이스의 역활만 하면 충분함으로 맴버함수의 구체적인 구현 내용은 나타나지않고
함수명(Function Prototype)만표시한다. 객체를 불러서 사용하는 외부에서는 구체적인 외부내용은 볼
필요가 없기때문이다. 외부에서 이파일만 보고 메세지를 던져야 하는사람을 위해서 메세지가
구체적으로 무엇을 해주는 것인지 쉬벡 알아볼수 있도록하여야함(주석처리)
-맴버함수중 클래스명과 동일한 함수명을 사용하되 리턴타입을 선언하지않는 함수가
"생성자(Constructor)"함수이다.
이함수는 문자 그대로 새로운 객체를 만드는 함수로써, 객체의 선언시 자동으로 불려져온다.
반면,객체를 없애고 그객체가 사용하던 메모리 공간을 운영체제에게 반납하기 위한 함수가
"소멸자(Destruct)"함수이다.
소멸자 함수는 클래스명앞에 물결(Tilde,~)표시로 구분하며, 생성자 함수와 마찬가지로 리턴타입을
선언하지 않음.
-C++클래스 선언의 두번째 섹션은 Private 라는 키워드로 시작, 이부분은 사적인것으로 외부사용자와
공유하는 부분은 아니다.
즉,이섹션에 선언된 변수나 함수를 읽고 쓰려고 외부에서 직접접근을 할수없다.
이부분을 접근할수 있는 자격을 가진것은 자체클래스 맴버함수 뿐이다.
일반적으로 Private섹션에 나타내는것은 맴버함수를 수행하는데 필요한 객체의 내부 저장공간.
즉, 변수들로써 이를 C++에서는 맴버데이터라고 부른다. 객체자신의 변화상태를 나타내는 변수라는
의미에서 객체지향에서는 이를 "상태변수:라고도한다.
②구현파일
-구현함수에서는 클래스명을 먼저쓰고, 콜론(:) 두개를 붙인다음. 이어서 메세지명을 써야한다
ex) Card::card()
이렇게 함으로써, 어느클래스에 속한 함수인지 나타낼수 있다.
같은 이름의 메세지라 할지라도, 클래스에따라서 처리방식이 달라질수있기 때문이다.
③메세지전달요령
-어떤클래스에 속한 객체를 선언하려면 클래스명다음에 객체를 선언.
ex)Card MyCard;
Card는 클래스 MyCard는 해당클래스에 속한 객체명.
-C++에서 메세지전달은 메세지를 받을 객체 다음에 점을 찍고 메세지명을대면된다.
ex) MyCard.Flip();
필요하다면 괄호안의 파라미터를 같이넣어 전달하면됨. 객체의 맴버데이터를 지정할때에도 객체명
다음에 점을찍고 변수명을 지정한다.
맴버함수 다음에는 파라미터가 없어도 빈괄호를 넣는것이 상례.
※ 괄호가 없을시 그것이 맴버함수인지,맴버데이터인지 헷갈릴수가있다.
④상속과 다형성
Public:
Triangle();
~Triangle();
void Draw();
float Area();
float GetBase();
Private:
float Base();
float Height();
};
이어받는것은 맴버함수와 맴버데이터 모두를 이어받는것.
-EX)1-1의 경우 triangle.T;라고 선언하고 T.Rotate(); 명령을 내릴수도있다. 맴버함수가 없음에도 이러한
명령을 내릴수있는것은 상위클래스인 Class Shape에 Rotate라는 맴버함수가 정의되고 구현되어있기
때문. 즉, 상속에 의한것임.
-T.Rotate();라고한다면 T클래스인 triangle 클래스에 해당함수가 있는지 먼저 검색함. 만약 해당함수가
있다면, triangle클래스에 선언된 함수가 직접실행. 그곳에 없을때에 한해서만 그 상위 클래인 Shape
클래스로 올라가서 , 가장먼저선언된것이 사용된다. 실행시 일어난다는 의미에서 "동적연결"이라함.
-연산자 오버로딩 ▶ 동일연산자에 두개이상의 의미를 부여하는것.
4.절차적설계와비교
-절차적 설계에는 어떤작업을 함수로 정의하고 이를 반복해서, 호출함으로써 재사용성을 높임.
반면 객체 지향설계는 모든 함수를 수행할수 있는 객체를 우선시한다. 어떤객체를 설정하여 그객체가
할수있는 모든 기능을 한군대 모아놓는 접근방법이 재사용 면에서는 더욱유리하다.
객체지향에서 무엇보다 중요한것은 인터페이스와 구현의분리이다.
외부에서 객체를 사용하는 사람의 입장엣서는 인터페이스만 알면된다. 객체 내부가 구체적으로 어떻게
구현되는지 몰라도된다. 이처럼 내부가 외부에 공개되지않도록 "외부와 벽을 쌓고있다"라는 의미에서
이를 "인캡슐레이션"이라고한다.
설정
트랙백
댓글
글
MC516K -CPU: Dual 2.2
RAM:4G
HDD: W.D 750G(5400RPM)
G/C: Gforce 320M
Moniter: 13.3"
O/S : Mac OSX(Lion) / BootCamp : Windows7 Ultimate
Used: KeyNote, Xcode, Cocos2d, box2d, openGL
한성 보몬 LV.63
CPU: i7 2.4(Turbo Boost 3.2)
RAM: 16G DDR3 - 10600
HDD: SSD intel 80G/ WD 650G(Black 7200rpm)
G.F : Gforce 560M(1.5G)
Moniter: 15.6"
O/S: Windows 7 Ultimate / VMware(Linux, MacOSx) 예정
Used: Visual Studio/ Unity
데탑(애니감상용이라 패스 ㅋㅋ)
RECENT COMMENT