20140401 (함수 포인터, void 포인터)

32일차

 

 

------------------------

함    수    포    인    터

------------------------

- 함수의 주소값을 저장하는 포인터.

먼저 이 포인터를 선언하기 위해서는 Data Type을 알아야한다.

Data Type은 Prototype(함수원형)에서 이름 부분만 (*)로 바꾸면 된다.

ex)

int main()                                main함수의 Data Type은

{ 명령어들 }                                   int (*)()  이다

void test()                               test함수의 Data Type은

{ 명령어들 }                                  void (*)()  이다

int printf(const char *, ... )        printf함수의 Data Type은

                                                   int (*)(const char *, ...)  이다

 

 

- 함수 포인터 선언 및 사용

#include <stdio.h>

void test()
{
  int (*fp)(const char *, ...) = printf;

  (*fp)("hello \n");  //  C++에서는 괄호를 넣지않으면 오류라고 한다.

  fp("hello \n");  //  C에서는 위와 밑에 둘 다 가능.

  
  return ;
}

int main()
{
  void (*fp)();
  
  fp = test;

  fp();

  return 0;
}

위와 같은 방법으로 사용한다.

 

 

 

 

-------------------------

void  형    포  인  터

-------------------------

- Data Type이 void * 형이다.

타입을 안가리고 그 주소값을 warning 없이 다 받을 수 있다.

그러나 값을 가리키는 *를 붙이면 자료형이 얼만큼 인지 모르니

사용할 수 없다.

캐스팅을 하면 사용가능.

ex)

#include <stdio.h>

int main()
{
  void *  vp;
  int  iNum = 500;
  char  cNum = 100;

  vp = &cNum;
  *((char *)vp) = 99;

  vp = &iNum;
  *((int *)vp) = 400;

  printf("%d \n", cNum);
  printf("%d \n", *((int *)vp) );
  printf("%d \n", iNum);  

  return 0;
}

위에 *((char *)vp) 식으로 char * 형이라고 캐스팅을 해서 사용.

 

 

 

아래 소스는 HexaView 코드인데

void * 가 사용되는 예를 보자.

#include <stdio.h>

void HexaView(void * vpData);

int main()
{
  int  iNum = 0x12345678;

  HexaView(&iNum);

  return 0;
}

void HexaView(void * vpData)
{  
  int iCnt;
  int iCnt2;
  
  printf("===============================================================================\n");
  printf("= ADDRESS                         HEXA                             ASCII      =\n");
  printf("=-----------------------------------------------------------------------------=\n");
  
  for(iCnt2=020>iCnt2; ++iCnt2)
  {

    //----------------------------//
    //---      Address Part Start      ---//

    printf("= %08X  "vpData);

    //---      Address Part End       ---//
    //----------------------------//
  


    //---    Hexa View Part Start    ---//

    for(iCnt=016>iCnt; ++iCnt)
    {
      if(7 == iCnt)
      {
        printf("%02X  "(*((unsigned char *)vpData)) );
      }
      else
      {
        printf("%02X "(*((unsigned char *)vpData)) );
      }
      vpData = ((unsigned char *)vpData) + 1;
    }
    //---    Hexa View Part End    ----//
    //----------------------------//



    //----------------------------//
    //---        ASCII Part Start       ---//

    vpData = ((unsigned char *)vpData) - iCnt;
    for(iCnt=016>iCnt; ++iCnt)
    {
      if(0x20 <= (*((unsigned char *)vpData)) && 0x80 > (*((unsigned char *)vpData)))
      {
        printf("%c"(*((unsigned char *)vpData)));
      }
      else
      {
        printf(".");
      }
      vpData = ((unsigned char *)vpData) + 1;
    }
    //---        ASCII Part End        ---//
    //----------------------------//
    printf(=\n");
  }  
  printf("===============================================================================\n");

  return ;
}

위에 연한 빨강색 바탕으로 강조된 곳들이

void *를 사용한 곳들이다.

main 함수에서 HexaView 함수를 호출 할 때에

void *를 사용하지 않았다면

HexaView( (unsigned char *)&iNum );

이런식으로 함수를 호출할 때마다 캐스팅을 해줘야 하기때문에

편의성의 위해서 작성할 때 좀 더 코드를 길게 적어주면 좋다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

설정

트랙백

댓글