POST

C언어 함수 포인터 변수

포인터란? - 바로가기


프로그래머가 정의하는 모든 함수는 프로그램 실행 시 '메인 메모리'에 저장되어서 실행이 된다.

그리고 함수의 이름은 메모리상에 저장된 함수의 주소 값을 의미한다.


그럼 함수 포인터 변수를 어떻게 선언 해야 할까?

우선 함수 포인터의 포인터 형을 결정 해야한다. 아래의 문장을 보자.

int simple_func(int num) { . . . }

이 함수의 반환형은 int 이며 매게변수의 선언은 int num이며 함수의 이름은 simple_func는 함수 이름이며 함수의 주소값을 의미하는 상수형태의 함수 포인터가 된다. 자 여기서 simple_func의 형(type)은 무엇일까?


 우리는 포인터의 형(type)은 반환형과 매게변수의 선언형태를 기준으로 구분하기로 약속 되어있다.


따라서 simple_func의 포인터형은 "반환형이 int이고 매게변수로 int형 변수가 하나 선언된 포인터 형(type)입니다." 라고 할 수 있다.


그렇다면 이제 함수의 주소 값(함수 포인터의 값 simple_func)을 저장할 수 있는 포인터 변수는 어떻게 선언 해야할까?

포인터 변수에는 반환형 정보와 매게변수의 선언 정보가 모두 표현되어 있어야한다.

아래의 문장을 보자.

int (*fptr) (int)

우리는 위의형식처럼 함수 포인터 변수를 선언하자고 약속이 되어있다.


int - 해당 함수의 반환형을 뜻한다.

(*fptr) - 포인터 변수

(int) - 해당함수의 매개변수의 형태


아래의 소스 코드를 보면 이해가 빠를 것이다.

#include<stdio.h>


void simple_adder(int n1, int n2);

void show_string(char *str);


void main(void) {

char *str = "Function Pointer";

int num1 = 10, num2 = 20;

void(*fptr1) (int, int) = simple_adder; // 함수 포인터 변수

void(*fptr2) (char *) = show_string; // 함수 포인터 변수

/*함수 포인터 변수에 의한 호출*/

fptr1(num1, num2);

fptr2(str);

}


void simple_adder(int n1, int n2) {

printf("%d + %d = %d\n", n1, n2, n1 + n2);

}


void show_string(char *str) {

printf("%s\n", str);

}




그리고 위의 예제처럼 사용할수도 있지만 매게변수의 선언으로 함수 포인터가 올 수 있다.

이것을 이용하여 아래의 소스코드처럼 전달되는 인자에 따라서 달리 동작하는 함수의 정의도 가능하다.


#include<stdio.h>


int who_is_first(int age1, int age2, int(*cmp)(int n1, int n2));

int older_first(int age1, int age2);

int younger_first(int age1, int age2);


int main(void) {

int age1 = 20;

int age2 = 30;

int first;

printf("입장순서 1\n");

first = who_is_first(age1, age2, older_first); // older_first전달

printf("%d세와 %d세 중 %d세가 먼저 입장!\n\n", age1, age2, first);


printf("입장순서 2\n");

first = who_is_first(age1, age2, younger_first); // younger_first전달

printf("%d세와 %d세 중 %d세가 먼저 입장!\n\n", age1, age2, first);

return 0;

}


int who_is_first(int age1, int age2, int (*cmp)(int n1, int n2)) {

return cmp(age1, age2); // 전달되는 인자에 따라 다른 함수를 실행한다.

}


int older_first(int age1, int age2) { // 나이가 많은 순

if (age1 > age2)

return age1;

else if (age1 < age2)

return age2;

else

return 0;

}


int younger_first(int age1, int age2) { // 나이가 적은 순

if (age1 < age2)

return age1;

else if (age1>age2)

return age2;

else

return 0;

}


위 코드의 실행 순서

1 - first 변수에서 who_is_first함수 호출

2 - 전달받은 함수 포인터 변수를 이용하여 해당 함수 호출

3 - 호출된 함수에서 크기 비교후 who_is_first로 값 반환

4 - who_is_first에서 first변수로 값 반환&저장


이렇듯 함수 포인터를 이용해 함수의 동작 방식에 유연성을 제공할 수도 있다.




공감 버튼 눌러주세요 ^^