1 함수포인터의 사용 

1.1 함수포인터란 

요즘 C 하는 개발자를 찾기가 힘들던가요 ? 여기 저기 C언어 개발자를 소개시켜 달라는데, 사람이 없어서 난리입니다.

C언어 하면 떠오르는게 포인터죠. 데이터의 위치를 가리키는 데이터 타입라고 생각하면 간단한 개념이긴 한데, 개념이 단순할 뿐 잘 다루기는 쉽지 않습니다. 커널이 관리하는 메모리를 낮은 수준에서 직접 건드리기 때문입니다. 툭하면 다른 프로세스의 메모리 영역을 침범해서 프로그램이 뻗어 버리고, 좀 잘 돌아간다 싶으면 메모리를 해제하지 않아서 모든 메모리를 다 써버리는 문제가 발생합니다.

전혀 추상화 되 있지 않다는 얘기죠. 그러니 사람이 직접 추상화 해줘야 합니다. 예컨데 할당한 메모리를 초과하지 않게 하거나, 메모리 해제를 관리하는 코드를 추가하거나 하는 등이죠.

함수 포인터는 데이터영역 대신에 함수를 가리키겠다는 것을 의미합니다. 어차피 컴퓨터는 코드든 데이터든 동일한 형태로 보기 때문에, 데이터를 가리키는 것과 그다지 차이는 없습니다.

지나가는 얘기. 요즘 언어들은 포인터를 직접 사용하지 않습니다. 모두 추상화 되있죠. 개발자는 얼마만큼 메모리를 할당해야 하는지, 혹 다른 프로세스의 메모리 영역을 침범하지는 않을지 메모리 누수가 발생할지 등에 대해서 고민할 필요 없이 프로그램을 만들 수 있습니다.

요즘 같은 때에 C는 철지난 언어같아 보입니다. 하지만 여전히 Java와 함께 가장많이 사용하는 언어입니다. 언어별 사용율 보러가기

1.2 함수 포인터 선언 

다음은 함수포인터를 선언하기 위한 전형적인 방법이다.
return_type (*function)(arg1, arg2, ...);
가리키기 위한 함수의 매개 변수와 반환 값을 잘 맞춰주면 됩니다.
예를 int hello(char *) 라는 함수를 가리키는 함수포인터를 선언하고자 한다면 아래와 같이 선언하면 됩니다.
int (*func_name)(char *);

다음은 간단한 함수 포인터 사용 예제입니다.

#include <stdio.h>
void hello(char *name)
{
    printf ("Hi %s\n", name);
}

int main()
{
    void (*Func)(char *);
    Func = hello;
    Func("test");
}
간단한 코드입니다. void 반환 값을 가지고 매개 변수로로 캐릭터 포인터를 가지는 함수포인터 Func를 선언한 다음, hello 함수를 가리키게했습니다. 이제 함수 포인터가 가리키는 hello 함수를 호출할 수 있습니다.

1.3 함수포인터사용 용도 

함수 포인터의 문법은 비교적 쉽게 이해할 수 있습니다. 문제는 어디에 왜 사용하느냐 하는 거죠. 함수 포인터라는 것은 함수를 한단계 추상화 하겠다는 겁니다. 개발자에게는 인터페이스만 제공하고 용도에 맞게 사용하게 만드는게 목표입니다.

함수 포인터의 목적을 이해하면, 어디에 써야할지 감이 잡힐 겁니다.

Strategy Pattern, 콜백함수 등

1.4 Generic 함수(알고리즘)의 개발 

각 학생의 과목별 성적데이타가 있고, 과목별 최고 점수를 가져오는 프로그램이 있다고 가정하겠습니다 처음에 이 프로그램은 각 과목중 "국어"의 최고 점수만을 가져오도록 만들었습니다. 그런데 "수학" 최고 점수만을 가져오도록 변경하고 싶군요 떻게 해야 할까요 ? 혹은 최고 평점을 가져오기를 원할수도 있것 겁니다.

물론 모든 경우에 대해서 고유의 작업을 하는 함수를 여럿 만들 됩니다만 유지/보수성이 떨어지겠죠. 이 경우 입력과 출력의 데이터 타입이 같으므로 일반적으로 사용할 수 있는 함수를 만든다면 좀 더 유지/보수가 용이한 코드를 만들 수 있을 겁니다. 함수 포인터를 이용해서 이런 일을 할 수 있습니다.

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <vector>

using namespace std;

typedef struct _pinfo
{
    char name[12];  
    int  math;
    int  korean;
    int  eng;
} pinfo;

void printmax(vector<pinfo> va, void (*SortFunc)(vector<pinfo>))
{
    printf("최고 성적 출력 프로그램\n");
    SortFunc(va);
}   

void engmax(vector<pinfo> va)
{
    int max = 0;
    int index = 0;
    for (int i = 0; i < va.size(); i++)
    {
        if (va[i].eng > max)
        {
            max = va[i].eng;
            index = i;
        }
    }
    printf("영어 최고점수 획득자는 %s : %d\n", 
        va[index].name,
        va[index].eng);
};

int main()
{
    pinfo myinfo;
    vector<pinfo> va;

    myinfo.korean = 80;
    myinfo.eng    = 65;
    myinfo.math   = 99;
    strncpy(myinfo.name, "yundream", 12);
    va.push_back(myinfo);

    myinfo.korean = 90;
    myinfo.eng    = 65;
    myinfo.math   = 74;
    strncpy(myinfo.name, "kknd", 12);
    va.push_back(myinfo);

    myinfo.korean = 63;
    myinfo.eng    = 88;
    myinfo.math   = 55;
    strncpy(myinfo.name, "junny", 12);
    va.push_back(myinfo);

    printmax(va, engmax);
}
이 코드에는 printmax라는 함수가 있습니다. 이 함수는 최고 값을 출력하는 일을 합니다. 최고 값을 계산하는 코드를 포함하는 함수는 함수 포인터로 받기로 했습니다. 예제 프로그램에서는 engmax를 포인트 했습니다. 만약 최고 평점자에 대한 정보를 출력하길 원한다면 다음과 같은 함수를 만들어서 printmax에 매개 변수로 넘기면 됩니다.

void avgmax(vector<pinfo> va)
{
    int max   = 0;
    int total;
    int index = 0;
    for (int i = 0; i < va.size(); i++)
    {
        total = (va[i].eng + va[i].math + va[i].korean);
        if ( total > max)
        {
            max = total;
            index = i;
        }
    }
    printf("최고평자 점정보 : \n");
    printf("이름 : %s\n", va[index].name);
    printf("영어 : %d\n", va[index].eng);
    printf("국어 : %d\n", va[index].korean);
    printf("수학 : %d\n", va[index].math);
    printf("평점 : %.2f\n", (float)max/3.);
}
아래와 같이 printmax 를 호출하면 됩니다.
printmax(va, avgmax);

이처럼 함수 포인터를 넘김으로 인해서, 프로그래머는 필요에 따라 원 소스의 큰 변화없이 자기가 필요로 하는 코드만 추가하는 식으로 프로그램을 쉽게 확장시킬수 있습니다.




출처 : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/C/Documents/FunctionPointer

VIM 명령어 정리

 

 

1. 저장 및 종료

명령어

설명

:w

저장

:w file.txt

file.txt 파일로 저장

:w » file.txt

file.tx파일에 덧붙여서 저장

:q

vi 종료

:q!

vi 강제 종료

ZZ

저장 후 종료

:wq!

강제 저장 후 종료

:e file.txt

file.txt파일을 불러옴

:e

현재 파일을 불러옴

:e#

바로 이전에 열었던 파일을 불러 옴

 

 

2. 입력모드 전환

a

커서 위치 다음칸부터 입력

A

커서 행의 맨 마지막부터 입력

i

커서의 위치에 입력

I

커서 행의 맨 앞에서 부터 입력

o

커서의 다음행에 입력

O

커서의 이전 행에 입력

s

커서 위치의 한글자를 지우고 입력

cc

커서위치의 한 행을 지우고 입력

 


3. 이동

h

왼쪽으로 이동

l

오른쪽으로 이동

j

아래행으로 이동

k

위 행으로 이동

또는 W

다음 단어의 첫 글자로 이동

또는 B

이전 단어의 첫 글자로 이동

또는 E

단어의 마지막 글자로 이동

<CR>

다음행 첫  글자로 이동

^

그행의 첫 글자로 이동

$

그 행의 마지막 글자로 이동

+

다음 행의 첫 글자로 이동

-

위 행의 첫 글자로 이동

(

이전 문장의 첫 글자로 이동

)

다음 문장의 첫 글자로 이동

{

이전 문단으로 이동

}

다음 문단으로 이동

H

커서를 화면 맨 위로 이동

z<CR>

현재 행을 화면의 맨우로 이동

M

커서를 화면 중안으로 이동

z.

현재 행을 화면의 중앙으로 이동

L

커서를 화면 최하단으로 이동

z-

현재 행의 화면의 최하단으로 이동

[n]H

커서를 위에서 n행으로 이동

[n]L

커서를 아래에서 n행으로 이동

ctrl+u

반 화면 위로 스크롤

ctrl+d

반 화면 아래로 스크롤

ctrl+b

한 화면 위로 스크롤

ctrl+f

한 화면 아래 스크롤

gg 또는 1G

문서의 맨 처음으로 이동

G

문서의 맨 마지막 행으로 이동

[n]G 또는 :[n]

n행으로 이동


 

4. 삭제

또는 dl

커서 위치의 글자 삭제

또는 dh

커서 바로 앞의 글자 삭제

dw

현재 위치부터 스페이스 까지 삭제

diw

현재 위치에 있는 단어 삭제

dd

커서가 있는 행을 삭제

[n]dd

현재 커서 부터 아래 n번째 줄까지 삭제

dj

현재 커서와 아래 줄 삭제

[n]dj

현재 커서 부터 아래 n+1번째 줄까지 삭제

dk

현재 커서와 윗로 n+1번째 줄까지 삭제

[n]dk

현재 커서와  줄 삭제

또는 d$

현재 커서가 있는 위치부터 행 끝까지 삭제

d0 또는 d^

현재 커서가 있는 위치부터 행 시작 까지 삭제

 

 

5. 복사 & 붙여넣기

yy 또는 Y

커서가 있는 한 행 복사

p

현재 커서에 붙여 넣기행 복사 일 경우 아래 줄에 붙여넣음.

P

현재 커서위치의 앞행에 붙여 넣기행 복사일 경우에는  줄에 붙여 넣음

[n]yy 또는 [n]Y

커서가 위치한 이후로 n행 복사

[n]p

n번 만큼 붙여넣기 반복

 

 

6. 블록 지정

v

블록 지정

V

줄단위 블록 지정

ctrl+v(윈도우에서는 ctrl+q)

비쥬얼 블록 지정

블록 지정 중 명령

y

블록 복사 하기

r

치환

d

지정 블록 지우기

U

대문자로 바꾸기

u

소문자로 바꾸기

~

대소문자 전환

J

행 합침

:

선택 영역에 대하여 ex명령

<

행 앞에 탭 제거

>

행 앞에 탭 삽입

 

 

7. 문자열 탐색 및 치환

/[문자열]

문자열 탐색

:s/old/new

현재 행의 처음 old new로 교체

:s/old/new/g

현재 행의 모든 old new로 교체

:10,20s/old/new/g

10행부터 20행까지 모든 old new로 교체

[블록지정중]:s/old/new/g

지정 블록 내에서 모든 old new로 교체

:-3,+4s/old/new/g

현재 커서 위치에서 위로 3행 아래로 4행까지의 old new로 교체

:%s/old/new/g

문서 전체에서 old new로 교체

:%s/old/new/gc

문서 전체에서 old new로 확인하며 교체

:g/pattern/s/old/new/g

pattern이 있는 모든 행의 old new로 교체

 

 

8. vim 정규 표현식

^

행의 첫 문자([]안에서는 not의 의미)

$

행의 끝

.

아무 문자나 한 문자 의미

\|

or의 의미

[ ]

[]사이의 문자 중 하나

\{min,max\}

min이상 max이하 반복됨

*

앞의 내용이 0번 이상 반복됨

\+

앞의 내용이 1번 이상 반복됨

\<

단어의 시작

\>

단어의 끝

\n

새 행 문자

\t

탭 문자

 

 

9. vim 확장 정규 표현 문자열

\i

변수 지정에 사용되는 문자들 [0-9A-Za-z]

\I

\i와 같지만 숫자는 제외

\k

keyword로 사용하는 문자 [_\.\-0-9A0Za-z]

\f

파일 이름으로 사용하는 문자

\p

프린트 가능한 문자

\P

\p와 같지만 숫자는 제외

\s

whitespace character(공백과 탭)

\S

non-whitespace character

\d

숫자 [0-9]

\D

숫자가 아닌 문자 [^0-9]

\x

16진수 숫자 [0-9A-Fa-f]

\X

16진수 숫자가 아닌 문자 [^0-9A-Fa-f]

\o

8진수 숫자 [0-7]

\O

8진수 숫자가 아닌 문자 [^0-7]

\w

영문 단어의 시작에 사용되는 문자 [0-9A-Za-z-]

\W

영문 단어에서 사용되지 않는 문자 [^0-9A-Za-z-]

\h

영문 단어의 시작에 사용되는 문자 [A-Za-z-]

\H

영문 단어의 시작에 사용 되지 않는 문자 [^A-Za-z-]

\a

모든 알파벳 [A-Za-z]

\A

알파벳이 아닌 문자 [^A-Za-z]

\l

소문자 [a-z]

\L

소문자가 아닌 문자 [a-z]

\u

대문자 [A-Z]

\U

대문자가 아닌 문자 [^A-Z]

\e

Esc

\t

Tab

\r

캐리지 리턴

\b

백스페이스

\n

새 행

 

 

10. POSIX 문자 클래스

문자 클래스

내용

[:alnum:]

알파벳과 숫자 [A-Za-z0-9]

[:alpha:]

알파벳 [A-Za-z]

[:cntrl:]

제어 문자

[:blank:]

탭과 공백 문자

[:digit:]

숫자 [0-9]

[:graph:]

제어문자와 공백 문자를 제외한 문자

[:lower:]

소문자 [a-z]

[:upper:]

대문자 [A-Z]

[:print:]

제어문자를 제외한 문자즉 프린터 할 수 있는 문자

[:punct:]

[:graph:]문자 중 [:alnum:]을 제외한 문자. ex)!,@,#,$,%,^....

[:space:]

화이트스페이스 ex)공백케리지 리턴새행수직탭폼필드

[:xdigit:]

16진수

 

 

11. 파일 버퍼

:files 또는 :ls 또는 :buffers

버퍼 목록 나열

:b[n]

n번 버퍼로 이동

:bd[n] 또는 :bw[n]

n번 버퍼를 삭제 (n이 없으면 현재의 버퍼를 삭제)

:bp[n]

이전 버퍼로 이동,n 붙이면 n번만큼 이전 버퍼로 이동

:bn[n]

이후 버퍼로 이동,n 붙이면 n번만큼 이후 버퍼로 이동

:sb[n]

창을 수평분할 하여 n번 버퍼를 로드

:bf

첫 번째 버퍼로 이동

:bl

마지막 버퍼로 이동

 

12. Tab

Vim 7.0부터 추가된 기능

:tabnew

새로운 탭을 열기

:tabnew b.txt

b.txt가 존재하면 열고없으면 새로 만들어서 연다

:tabf b.txt

b.txt가 존재하면 열고없으면 에러 발생

:tabn[n]

다음 탭을 열기,n 붙이면 n번 만큼 이동

:tabp[n]

이전 탭을 열기,n 붙이면 n번 만큼 이동

:tabs

탭 목록 보기

:tabclose

탭을 닫기

:tabfirst

첫번째 탭을 열기

:tablast

마지만 탭을 열기

:tabdo %s/old/new/g

모든 탭에 적용을 원할 때 (예 모든탭에서 old new로 변경)

 


13. 다중 창 관련 명령

명령모드

ex모드

결과

창생성

CTRL-W s

:[N]sp[plit]

현재 파일을 두 개의 수평 창으로 나눔

CTRL-W v

:[N]vs[plit]

현재 파일을 두 개의 수직 창으로 나눔

CTRL-W n

:new

새로운 수평 창 생성

CTRL-W ^ 또는 CTRL-W CTRL-^

 

수평 창으로 나누고 이전 파일의 오픈

CTRL-W f

 

창을 수평으로 나누고 커서 위치의 파일 오픈

CTRL-W i

 

커서 위치의 단어가 정의된 파일을 오픈

창삭제

CTRL-W q

:q[uit]!

현재 커서의 창을 종료

CTRL-W c

:close

현재 커서의 창 닫기

CTRL-W o

:on[ly]

현재 커서의 창만 남기고 모든 창 삭제

창이동

CTRL-W h

 

왼쪽 창으로 커서 이동

CTRL-W j

 

아래쪽 창으로 커서 이동

CTRL-W k

 

위쪽 창으로 커서 이동

CTRL-W l

 

오른쪽 창으로 커서 이동

CTRL-W w

 

창을 순차적으로 이동

CTRL-W p

 

가장 최근에 이동한 방향으로 이동

CTRL-W t

 

최상위 창으로 이동

CTRL-W b

 

최하위 창으로 이동

창이동

CTRL-W r

 

순착으로 창의 위치를 순환

CTRL-W x

 

이전 창과 위치를 바꿈

CTRL-W H

 

현재창을 왼쪽 큰화면으로 이동

CTRL-W J

 

현재창을 아래쪽 큰화면으로 이동

CTRL-W K

 

현재창을 위쪽 큰화면으로 이동

CTRL-W L

 

현재창을 오른쪽 큰화면으로 이동

창 크기 조정

CTRL-W =

 

창의 크기를 모두 균등하게 함

CTRL-W _

 

수평 분할에서 창의 크기를 최대화

CTRL-W |

 

수직 분할에서 창의 크기를 최대화

CTRL-W [N]+

:res[ize] +N

창의 크기를 N행 만큼 증가

CTRL-W [N]-

:res[ize] -N

창의 크기를 N행 만큼 감소

CTRL-W [N]>

 

창의 크기를 오른쪽으로 N칸 만큼 증가

CTRL-W [N]<

 

창의 크기를 오른쪽으로 N칸 만큼 감소

다중창 사용의 경우 대부분 붙여서 사용하는 명령어는 CTRL을 같이 눌러도 똑같은 역활을 하는 경우가 많다
) CTRL-W j  CTRL-W CTRL-J와 같다.

 

 

14. 마킹 및 마킹위치로 이동

m[a-z0-9]

파일내에서 마킹현재 버퍼내에서만 이동 함 예)ma

m[A-Z]

전체영역에서 마킹다른 파일로도 이동 함.

`[A-Za-z0-9]

마킹된 위치로 돌아감 예)`a

’[A-Za-z0-9]

마킹된 행의 처으으로 이동함)‘a

직전에 커서가 위치하던 행의 처음

``

직전의 커서 위치로 이동

’”

이전에 vim으로 현재 파일을 닫았을 때 커서가 있던 행의 처음으로 이동

`"

이전에 vim으로 현재 파일을 닫았을 때 커서가 있던 위치로 이동






'Programming > Tool' 카테고리의 다른 글

[cscope] cscope 사용법  (0) 2013.06.18
[ctags] ctags 사용법  (0) 2013.06.18
[VI/VIM] 개발 환경 설정  (0) 2013.06.18
[VI] VI/VIM 명령어 정리  (0) 2013.04.18
[Eclipse] 이클립스 단축키  (0) 2012.09.29
[tortoiseSVN] Windows에서 tortoiseSVN을 이용한 SVN 사용하기  (0) 2012.09.27

컴파일을 시도할 경우 컴파일이 실행되기 전에 전처리기 명령부터 처리된다.

전처리기는 # 로 시작하고 ; 를 붙이지 않으며 보이지 않게 소스 코드를 변경하며

컴파일러에게 지시를 내릴 수도 있다.

 

각각은 여기서는 명령어라는 용어를 사용했지만 정확하게는 directive(지시자라고 하는 것이 나을 지 모르겠다.

 

#include <header.h>

 

가장 흔히 볼 수 있는 전처리기이다해당 파일을 찾아서 컴파일러가 그 파일이 마치 현재 컴파일하는 소스 코드에 포함되어 있는 것같이 해준다. <> 는 표준 헤더 파일일 경우에 설정되어 있는 폴더에서 헤더 파일을 찾으며 “” 는 그 외 폴더에서 찾을 수 있는데 최우선으로 현재 프로젝트 폴더에서 찾게 된다.

 

#define

 

define 문은 여러 경우에 사용될 수 있는데 일반적으로 문자열 대치에 사용된다.

 

#define MAX 512

 

라고 하면 소스 코드에 있는 MAX 라는 문자를 모두 512 로 대치한다.

 

int Arr[MAX];

 

는 실제 컴파일러가 컴파일할 때는

 

int Arr[512];

 

로 대치될 것이다이것은

 

#define MAX 512

int Arr[MAX];

 

 

int Arr[512];

 

로 바뀐다고 생각하면 된다.

대치되는 문자 없이 그냥

 

#define MAX

 

로 사용되는 경우도 흔하다이것은 MAX 라는 문자열을 정의하지만 대치시키지는 않는다.

이렇게 사용하는 경우는 #ifdef ~ #elif ~ #else ~ #endif 문과 같이 사용되면 상당히 유용하게 사용된다.

 

#ifdef MAX

       cout << “Max is defined!” << endl;

#else

       cout << “Max is not defined!” << endl;

#endif

 

이렇게 사용하면 #define MAX  줄로 여러 버전의 실행 파일을 만들 수도 있다.

이런 것을 조건부 컴파일이라고 한다마지막 #endif  넣는 것도 잊지 말자.

 

#ifdef MAX

#elif defined(MIN)

#else

#endif

 

문이나

 

#if defined(MAX)

#elif defined(MIN)

#else

#endif

 

문등의 예제를  봐두기 바란다.

 

¨       관련된 주요 전처리기 명령어

 

¨       #ifdef 식별자

¨       #ifndef 식별자

¨       #undef 식별자

¨       #if defined(식별자)

¨       #if !defined(식별자)

¨       #elif

¨       #else

¨       #endif

 

#ifdef 등으로 식별자를 사용했으면

 

#undef 식별자

 

문으로 undef 하는 습관을 기르자. #undef 이후부터  식별자는 정의되지 않은 것으로 간주된다.

 

예제http://blog.naver.com/xtelite/50018568445

 

포함감시(Inclusion Guard)

 

여러 개의 헤더 파일(.h 또는 .hpp)과 구현 파일(.c 또는 .cpp) 들이 있을 경우 헤더 파일이 중복 포함되는 경우가 많다특히 C/C++에 입문한 지 얼마 안되는 사람들에게서 자주 나타나는 데 이런 경우 포함감시를 사용한다사실 포함감시 기능은 만드는 모든 헤더파일에 적용하도록 하자.

 

#ifndef FILENAME_H

#define FILENAME_H

 

// 여기에 헤더 파일의 모든 내용을 넣는다

 

#endif

 

이렇게 해 두면 두 번째 포함될 때 #ifndef 가 거짓이 되어 이 헤더 파일이 포함되지 않는다.

,

 

#include “filename.h”

#include “filename.h”

 

와 같이 하더라도 두 번째 헤더파일은 포함되지 않을 것이다. FILENAME_H 부분은 관례상 파일명을 이용해서 이렇게 명명한다. _FILENAME_H  __FILENAME_H__ 등 잘 사용되지 않는 문자열을 파일이름을 사용해서 만드는 것이다.

 

매크로 함수(Macro function)

 

매크로 함수도 전처리기로 흔히 사용된다다만 디버깅이 힘들다는 단점 때문에 점점 사용되지 않고 있기도 하다.

특히, C++의 경우 엄격한 형 검사를 하게 되는데 매크로 함수를 사용하게 되면 그 기능을 사용할 수 없으니 피해야 한다.

 

#define CUBE(x) ((x)*(x)*(x))

 

int x, y;

y = CUBE(x);

 

 

int x, y;

y = (x) * (x) * (x);

 

로 대치될 것이다매크로 함수를 사용한다면 ()를 남발하는 습관을 키워야 한다.

왜 그런지는

 

y = CUBE(3+4);

 

와 같은 경우에 직접 대치해 보면 알게 될 것이다.

 

C++ 사용자는 매크로 함수보다는 template이나 inline 함수를 사용해야 한다.

 

문자열 조작

 

#define SAY(x) printf(#x)

 

SAY(Hello, world!);

 

와 같이 식별자 앞에 # 를 붙이게 되면 자동으로 “x” 와 같이 “”로 둘러 싸 준다.

결과적으로

 

printf(“Hello, world!”);

 

로 대치될 것이다.

 

문자열 결합

 

## 는 두 개의 문자열을 결합해 준다.

 

#define Print(x) Print ## x

 

와 같이 된 경우

 

Print(One) 을 사용하면 PrintOne 이라는 문자열로 대치되고 Print(Two)  PrintTwo 라는 문자열로 대치된다잘 사용하면 아주 유용한 기능이 된다.

 

ASSERT()

 

대부분의 컴파일러는 ASSERT() 매크로를 가지고 있다여기서는 직접 하나 만들어 보자.

 

#ifndef DEBUG

#define ASSERT(x)

#else

#define ASSERT(x) \

       if ( ! (x) ) \

       { \

             printf(#x); \

             printf(“ is NULL on line %d in file %s”, __LINE__, __FILE__); \

       }

#endif

 

이 코드의 위에

 

#define DEBUG

 

한 줄 포함하면

 

#define ASSERT(x)

 

로 아무 일도 하지 않고 DEBUG가 정의되지 않으면 그 아래 함수가 정의된다.

디버그때만 코드가 생성되고 릴리즈시에는 코드가 생성되지 않게 할 수 있는 것이다.

 

여러 줄이 필요할 때는 \ 가 사용되었다는 것에 유의하자또한 내장 매크로인 __LINE__ 이나 __FILE__ 은 다음에 설명한다.

 

내장 매크로

 

컴파일 시에 컴파일러가 미리 정의하고 있는 매크로들이 있다.

각각 오른 쪽에 있는 내용으로 대치된다.

 

__DATE__ : 컴파일하는 날짜

__TIME__ : 컴파일하는 시간

__LINE__ : 현재 컴파일하고 있는 줄 번호

__FILE__ : 현재 컴파일하고 있는 파일의 이름

 

#error

 

컴파일러는 이 명령을 만나게 되면 해당 메지시를 출력하고 컴파일을 중지한다.

C++ 컴파일러에서만 동작하게 하는 다음 코드를 참조하자.

 

#if !defined(__cplusplus)

#error C++ compiler required.

#endif

 

__cplusplus  C++ 컴파일러일 경우에 정의되는 내장 매크로이다.

 

#pragma

 

#pragma 는 컴파일러마다 고유하게 사용할 수 있는 명령어이다따라서 그 문법은 컴파일러마다

다르고 그 종류도 많다.

 

예를 들어

 

#pragma once

 

같은 경우 위의 포함감시 기능을 컴파일러가 알아서 해 준다한 번 include 된 헤더 파일은 중복해서 포함되지 않도록 컴파일러가 처리해 준다.




출처 : http://blog.naver.com/xtelite?Redirect=Log&logNo=50023963913


 MFC 수업 때, 진행했던 프로젝트입니다. 모든 조들이 교수님께서 과제로 내주신 제스처수집기를 만들었습니다. 하지만 우리조는 뭔가 색다른 우리가 하고 싶은 것을 하고 싶었습니다. 그렇게 시작하게된 프로젝트입니다. 그리고 처음으로 웹상에 레파지토리에 소스관리한 첫 프로젝트입니다. 프로젝트에 대한 설명은 발표자료에 있습니다. 코드를 참고하시려는 분들은 참고하셔도 좋습니다.



프로젝트 네이버개발센터 URL : http://developer.naver.com/projects/ipaint/

+ Recent posts