C/C++
앞으로 시리얼과 TCP/IP, UDP/IP, UDS 강좌를 올리려 합니다. 그 전에 포인터 함수에 대해 먼저 말씀을 올리고자 합니다. 이유는 강좌의 마지막 장에는 제가 사용하고 있는 통신 라이브러리를 소개하려 합니다. 통신 방식이 다르더라도 사용하는 방법을 통일하기 위해 포인터 함수를 이용했거든요.
포인터 함수를 이용함으로써 통신 방식이 다르더라도 함수 이름과 과 함수의 인수를 통일할 수 있습니다.
물론 C++을 이용하면 더 간편하게 구현할 수 있지만 임베디드를 개발하시는 분들을 뵈면 C++ 보다는 C 를 애용하시더라 구요. 또한 라이브러리를 보시면 C++로 쉽게 변경하실 수 있기 때문에 C를 기준으로 설명을 드리도록 하겠습니다.
포인터 함수
포인터 함수를 소개하기에 앞서 아래와 같은 경우를 먼저 보겠습니다.
int a( int num){ return num; } int b( int num){ return num *10; } int c( int num){ return num *100;} int main() { int ndx; int jdx; ndx = 임의의 함수로부터 값을 얻음 switch( ndx) // ndx의 값에 따라 호출하는 함수가 다릅니다. { case 1 : jdx = a(); case 2 : jdx = b(); case 3 : jdx = b(); } }
프로그램을 보시면 ndx 변수에 따라 호출하는 함수가 다릅니다. 여기서 a() 함수나 b() 함수도 모두 메모리에 올라와 있는 함수이므로 당연히 함수도 메모리에 위치한 주소를 가지고 있을 것입니다.
위의 예제에서처럼 switch 또는 if 문을 사용하지 않고 함수의 위치, 즉 포인터 식으로 처리하면 어떨까요? 아래처럼 말이죠.
int main() { int () ptrFun[] = { a, b, c}; jdx = ptrFun[ndx] }
호출되는 함수가 많수가 많을 수록 편리하겠지요. 그러나 이것은 포인터 함수를 소개해 드리기 위해 보여 드린 간략한 사용 예일뿐 포인터 함수는 더 다양한 코드에서 사용할 수 있습니다.
일단 위의 예를 완성해 보도록 하겠습니다.
#include <stdio.h> int a( int num){ return num; } int b( int num){ return num *10; } int c( int num){ return num *100;} int main( void) { int (*ptr_fun[])(int) = { a, b, c}; int ndx; ndx = getchar(); // 문자 하나를 받아서 ndx = ( ndx & 0x0f) % 3; // 최 하위 니블 값에 3의 나머지 값을 얻음 // 결국 ndx는 키 입력에 따라 0, 1, 3가 됨 printf( "%dn", ptr_fun[ndx]( 2007)); // 키 입력에 따라 개별함수 호출 return 0; }
메모리에 위치한 함수의 주소를 받는 변수 ptr_fun에 대해 먼저 알아 보도록 하겠습니다.
int (*ptr_fun[])(int) = { a, b, c};
이렇게 선언 함으로서 함수의 형태가 int 값을 받고 int값을 리턴하는함수 int fun( int ndx) 의 메모리에 위치한 주소값을 받을 수 있는 함수 포인터를 정의한 것입니다.
만일 배열로 처리할 필요가 없다면, 즉 함수의 메모리 주소만 받겠다면,
int *ptr_fun(int)
이렇게 선언하시면 됩니다.
ndx = getchar();
ndx = ( ndx & 0x0f) % 3;
ndx에 문자 하나를 받아서 하위 니블의 값만 취합니다. 함수의 개수가 3개 이기 때문에 %3 으로 0, 1, 2 까지만 값을 가지도록 했습니다.
printf( "%dn", ptr_fun[ndx]( 2007));
ndx의 값에 따라 a(), b(), c()를 호출하게 됩니다. 프로그램을 실행한 후 0을 입력 후에 엔터키를 누르면 *1 에 대한 값을, 1을 입력하면 *10을, 2를 입력하면 *100한 값이 출력됩니다.
]$ ./a.out 0 2007 ]$ ./a.out 1 20070 ]$ ./a.out 2 200700 |
태그: *C언어