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=0; 20>iCnt2; ++iCnt2)
{
//----------------------------//
//--- Address Part Start ---//
printf("= %08X ", vpData);
//--- Address Part End ---//
//----------------------------//
//--- Hexa View Part Start ---//
for(iCnt=0; 16>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=0; 16>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 );
이런식으로 함수를 호출할 때마다 캐스팅을 해줘야 하기때문에
편의성의 위해서 작성할 때 좀 더 코드를 길게 적어주면 좋다.