반응형
:: 2007년 7월 6일 ::
 
  안녕하십니까?

장마도 한 풀 꺾인 무더운 여름이 시작되는 7월입니다.
한국 디벨로퍼웍스에서는 개발자 분들을 위하여 이클립스의 각종 플랫폼과 플러그-인에 대한 내용으로 시원한 기술 세미나를 개최합니다.

이클립스는 자바 개발도구일 뿐이라고 생각하십니까? 이번 기술 세미나에 참석하시면 그 이상의 새로운 사실들을 알게 되실 겁니다. 이클립스는 소프트웨어 개발에 관련된 어떤 것이라도 포함하는 범용 플랫폼으로 발전해 왔고, 이제 그 영역을 소프트웨어 개발 너머까지 넓혀 나가고 있습니다. 이제는 이클립스 안에서, 지역적으로 멀리 떨어져 있는 사람들간의 협업, 리치 클라이언트 개발, 애플리케이션 런타임 분석, 등의 일들을 모두 처리할 수 있습니다.

이번 세미나에서는 이클립스의 각종 플랫폼과 플러그-인 개발 소개 뿐 아니라, 몇 개의 이클립스 프로젝트를 선별하여, 그 성능을 보여주는 데모를 할 예정입니다.

IBM 디벨로퍼웍스가 제공하는 이클립스 세미나 및 이후 진행되는 무료 영화 관람의 기회를 놓치지 마시기 바랍니다!
 


 

 
 

 
시 간 내 용
12:30 - 13:00     등록 및 인사말
13:00 - 14:40     이클립스 커뮤니티에 대한 소개와 이클립스 프로젝트에
    대한 개요
    이클립스의 멀티-언어 지원
    웹 서비스와 자바 EE 애플리케이션을 포함한 웹 툴
    테스트, 성능 툴 플랫폼 프로젝트의 테스팅
14:40 - 14:50     휴식 BREAK
14:50 - 16:20     이클립스 협업/커뮤니케이션 프레임워크
    플러그-인 개발 환경
    리치 클라이언트 플랫폼
    이클립스의 다음 단계 및 IBM 이클립스 기반 제품 소개
16:20 - 16:30     Q&A / Closing
16:30 - 18:20     영화 관람 (상영작은 당일 개봉작 중 추후 결정)
 
top

더이상 구독을 원치 않으시는 분은 developerWorks에서 뉴스레터 [구독 취소]를 선택하여 주시기 바랍니다.
developerWorks 운영자에게 메일 보내기
Copyright ⓒ IBM Korea, Inc. All rights Reserved.


반응형
 

1. 함수 포인터란?

- 프로그램에서 함수 이름은 메모리에 로드된 그 함수의 실행코드 영역에서의 시작주소를 의미한다.

- 함수에 대한 포인터는 바로 그 함수의 시작 주소 값을 갖는 포인터이다.

 

함수 포인터 역시 포인터 변수이다. 일반 포인터 변수와 다른 점은 일반 포인터 변수가 변수의 주소 값을 저장하는 반면에 함수 포인터는 함수의 주소 값을 저정한다. 함수는 code부분이다. 즉 프로그래머가 짠 코드가 컴파일 되어서 기계 코드로 변환된 것이 바로 code이다. 프로그램이 실행되기 위해서는 이 code가 메모리에 올라가 있어야 한다. 여기서 어떤 함수에 대한 호출은 이 code 중에서 그 함수 부분으로 jump(이동) 하는 것이다. 바로 이 함수 부분이라는 것이 그 함수의 주소 값이 되는 것이고 이 함수의 주소 값을 저장하는 포인터가 함수 포인터인 것이다. C 언어는 함수 자체를 변수로 만들 수 없다. 대신 함수를 포인터하는 것은 가능하기 때문에 이것을 통해 함수를 포인터처럼 사용할 수 있다. 이 포인터가 가리키고 있는 곳의 함수를 실행시킬 수 도 있다.

 

예) main 함수와 printf 함수의 시작 주소 값을 출력한다.

       

#include <stdio.h>

 

main()

{

        printf("address of main : %u \n", &main);

        printf("address of printf : %u \n", &printf);

}

 

 

2. 함수 포인터의 용도

- 함수에 접근하기 위해 사용된다.

- 함수에 함수 자체를 실인수로 전달하기 위해 사용된다.

- 함수의 처리 결과가 함수일 때 그 함수에 대한 포인터를 돌려주기 위해 사용된다.

 

※ 함수 포인터에 대한 연산은 허용되지 않는다.

 

 

3. 함수 포인터의 선언

- 다른 포인터 변수와 마찬가지로 함수 포인터도 먼저 선언하고 사용해야 한다.

- 함수 포인터의 선언은 일반적으로 다음의 형식을 사용한다.

 

자료형 (*함수포인터명)(인자목록);

 

이 형식은 명시된 자료형을 돌려 주고 인자목록에 포함된 인자를 받는 함수에 대한 포인터를 선언한다.

 

- 함수 포인터 선언의 구체적인 예:

 

        ⓐ int (*f1)(int a);

        ⓑ char (*f2)(char *p[]);

        ⓒ void (*f3)();

 

  ⓐ 하나의 int형 인자를 받아들이고 int형 자료를 돌려주는 함수에 대한 포인터 f1을 선언한다.

  ⓑ char형에 대한 포인터 배열을 인자로 받아 char형의 값을 돌려주는 함수에 대한 포인터 f2를 선언한다.

  ⓒ 아무런 인자도 받지 않고 결과 값도 돌려주지 않는(void) 함수에 대한 포인터 f3를 선언한다.

 

- 함수 포인터 선언과 포인터를 돌려주는 함수 선언과의 차이:

        ⓐ int (*f1)(int a);

        ⓑ int *f2(int a);

 

  ⓐ 함수 포인터: 한 개의 int형 인자를 받아 int형 값을 결과로 돌려주는 함수에 대한 포인터 f1을 선언한다.

  ⓑ 포인터를 돌려주는 함수의 선언: 한 개의 int형 인자를 받아 int형 포인터 값을 결과로 돌려주는 함수를 선언한다.

 

※ 함수에 대한 포인터 선언은 반드시 포인터 이름과 간접연산자(*) 주위에 ( )를 사용해야 한다.

 

 

4. 함수 포인터의 초기화

- 함수 포인터를 선언하고 나면 이 포인터가 어떤 함수를 지시하도록 초기화해야 한다.

- 함수 포인터를 초기화할 때 인자목록과 return 자료형이 일치해야 한다.

- 함수 이름은 이름 자체가 주소를 의미한다. 따라서 함수 포인터에 함수의 주소값을 초기화하려면 다음과 같이 한다.

 

int add(int a, int b); => 함수의 prototype

int (*f1)(int x, int y); => 함수 포인터 선언

int add(int a, int b) { return a + b; }  => 실제 함수 정의 부분
 
f1 = add; => 적합

f1 = &add; => 적합

f1 = add(); => 오류(f1은 포인터, add()의 결과는 int)

f1 = &add(); => 오류(&부적당)

 

 

5. 함수 포인터의 활용

- generic한 함수(혹은 알고리즘)의 작성을 가능하게 한다.

- 잘 사용하면 유지/보수를 수월하게 한다.

- 함수 이름 자체는 배열의 이름처럼 한번 정해지면 바꿀 수 없는 포인터 상수이다. 그러나 함수 포인터는 변경이 가능하며 필요할 때마다 다른 함수를 지시하도록 설정할 수 있다.

 

예) 입력에 따라 함수포인터 fun에 지정되는 함수가 결정된다.

 

#include <stdio.h>

 

int add(int a, int b); /* 함수의 prototype */

int sub(int a, int b);

int mul(int a, int b);

int div(int a, int b);

 

main()

{

        int (*fun)(int x, int y); /* 함수 포인터 선언 */

        int a, b;

        char c;

 

        printf("Input (num op num) : ");

        scanf("%d %c %d", &a, &c, &b);

 

        switch (c)

        {

                case '+' :

                        fun = add;

                        break;

                case '-' :

                        fun = sub;

                        break;

                case '*' :

                        fun = mul;

                        break;

                case '/' :

                        fun = div;

                        break;

        }

        printf("%d %c %d = %d\n", a, c, b, fun(a,b));

}

 

int add(int a, int b)

{

        return a+b;

}

 

int sub(int a, int b)

{

        return a-b;

}

 

int mul(int a, int b)

{

        return a*b;

}

 

int div(int a, int b)

{

        return a/b;

}


- 함수 포인터 배열: 여러 개의 함수 포인터를 배열에 저장하여 사용할 수 있다.

 

int (*fun[3])(int, int);

 

int형 자료 두 개를 입력 받아 int형 결과를 돌려주는 함수 포인터 3개를 저장할 수 있는 배열이다.

 

예) 두 정수 a, b를 읽어서 합, 차, 곱을 구하는 예제로 함수 포인터의 배열을 사용한다.

 

#include <stdio.h>


int add(int a, int b); /* 함수의 prototype */

int sub(int a, int b);

int mul(int a, int b);

 

main()

{

        char op[] = {'+', '-', '*'};

        int (*fun[])(int x, int y) = {add, sub, mul};

        int a, b;

 

        printf("Input number(2 EA) : ");

        scanf("%d %d", &a, &b);

 

        for (i = 0; i < 3; i++)

        printf("%d %c %d = %d\n", a, op[i], b, fun[i](a,b));

  }

 

int add(int a, int b)

{

        return a + b;

}

 

int sub(int a, int b)

{

        return a - b;

}

 

int mul(int a, int b)

{

        return a * b;

}
 
- 함수 포인터를 인자로 전달하기: 함수명을 인자로 전달하거나 함수 포인터 자체를 함수의 인자로 보내고 받을 수 있다. 함수명을 실인수로 사용할 경우 호출당한 함수의 가인수는 함수 포인터가 된다.

 

예) 함수 포인터의 잔달


#include <stdio.h>


int print_add(int a, int b)

{

        printf("%d + %d = %d\n", (a, b, a+b);

}

 

int add(void (*fp)(int, int), int x, int y)

{

        fp(x, y);

}

 

main()

{

        add(print_add, 10, 5);

}
 
- 함수의 주소 값 전달

  add(think);     => think(); 함수의 시작 번지 값이 add() 함수의 인자이다.

  add(think());  => think(); 함수의 리턴 값이 add() 함수의 인자이다.

 

- 함수 포인터를 이용해 특정 번지로 점프하기

 

예1)

 

#include <stdio.h>

void main(void)

{

        unsigned int goaddr = 0x8120;  /* 8120H 번지임을 나타낸다. */

        void (*gofunc)(void);              /* 함수 포인터 선언 */

 

        gofunc = (void(*)()) goaddr;    /* 초기화 */

        (*gofunc)();                          /* 함수포인터 실행 */

  }

 

위 예에서는 void (*gofunc)(void);로 선언된 함수 포인터가 실제적으로 가리켜야 할 목적지 함수가 따로 없는 것처럼 보인다. 그러나 잘 보면 목적 함수는 다음과 같음을 알 수 있다.

 

void (*goaddr)();     : 목적함수

 

그리고 위 목적함수는 하나의 형(type)으로써 뒤의 goaddr을 cast한다. 이제 (*gofunc)();로 실행되면 컴퓨터의 PC(Program Counter) 또는 IP(Instruction Pointer)는 (*gofunc)(); 함수로부터 void (*goaddr)(); 함수로 넘어간다. 그리고 void (*goaddr)(); 함수의 시작번지는 0x8120 번지가 되는 것이다. 따라서 컴퓨터의 PC는 0x8120 번지로 점프하게 되는 결과를 낳는다.

 

예2)


#include <stdio.h>


void main(void)

{

        void (*gofunc)(void);             /* 함수 포인터 선언 */

 

        gofunc = (void (*)()) 0x8120;   /* 시작주소 초기화 */

        (*gofunc)();                          /* 함수포인터 실행 */

}


위 프로그램은 번거롭게 goaddr이라는 변수를 생략하고 직접 (*gofunc)();의 시작주소를 지정하였다. 이로써 확실히 알 수 있는 것은 포인터 함수의 시작주소의 캐스팅 형이 (void (*)())이 된다는 것이다.

 

예3) 단 한줄로 나타내보자.

 

#include <stdio.h>


void main(void)

{

        (*((void (*)()) 0x8120))();

}


이 한줄은 바로 0x8120번지로 점프하라는 명령어와 같다. 그러나 TurboC++ 3.0 에서는 위 명령이 유효하나 IC96에서는 무효하다(다음과 같은 에러 메시지가 뜬다).

 

iC-96 FATAL ERROR --

internal error: invalid directionary access, case 3

COMPILATION TERMINATED


그러나 방법은 있다. 아래와 같이 하면 IC96에서 에러 없이 멋지게 만들어낼 수 있다.

 

#include <80c196.h>         /* 표준 인클루드 파일 */

 

void main()

{

        (*(void (*)(void))(*(void (**)(void))0x8120))();

}

 

실제로 위와 같은 선언은 특히 Embedded System Programming에서 많이 사용되는 방법이다. 특히 80C196에서 이중 인터럽트 벡터 지정 시에 유용하게 사용될 수 있다.

반응형
블로그에는 기본적으로 스킨과 레이아웃 그리고 사이드바 형식을 정할수 있지만 그 이후에는 자신이 원하는대로 꾸밀수 있는 것들이 많이 존재합니다. 사이드바에 추가할수 있는 위젯, 배너, 버튼등 여러가지가 있으며 본문이나 스킨자체에도 많은 부분을 커스터 마이징 할수있습니다. 저한테도 유용했고 또 앞으로도 계속 쓰여질만한 링크들을 모아보았습니다.

Sammy's Blog - 페이지뷰 카운터 달기

Sammy's Blog - 인기글 리스트 달기

신날로그 - 인기글리스트 위젯 Spotplex

신날로그 - 직접 스킨 수정하는 방법

신날로그 - 실시간 방문자 수 확인하는 위젯

신날로그 - 파비콘 간단히 만들기

신날로그 - 시계 위젯달기

신날로그 - 방문자 남기는 MyBlogLog

재아 - 환경설정 메뉴들 바로가기 만들기

LEEGH.COM - 블로그 타이틀을 이미지로 바꾸는법

LEEGH.COM - 블로그에 메신져 달기

LEEGH.COM - 영어 번역 링크달기

LEEGH.COM - 일본 번역 링크달기

LEEGH.COM - 링크에 미리보기 가능한 Snap

LEEGH.COM - 별점 평가 위젯

Zooty - 특이한 시계 위젯

웹프로그래머 - 블로그에 채팅창 달기

웹프로그래머 - 블로그용 플래시 악세서리 6종

S2day - 모든 동영상 수집, 정리, 공유하는 위젯 VodPod

annotation - 작은 배너 만들어주는 사이트 모음

지크의 팁박스 - 블로그에 flickr 슬라이드 달기

알릭 - 블로그에 실시간 인기검색어 위젯달기

디자인로그 - 블로그 하트링 위젯 구현방법

Egg's - 펌핏의 최신글, 인기글 위젯

신날로그 - 애드센스 본문에 삽입하는 방법

블로그의 가치 돈으로 환산해주는 위젯


물론 찾아보면 훨씬 많은 위젯과 유용한 것들이 많겠지만 이정도 까지 해보았습니다. 혹시 추천하고 싶으신 위젯있으시다면 댓글로남겨주세요!^^

+ Recent posts