Dreaming developer

예비 개발자를 꿈꾸는 서연이의 기록일지

Together, Tomorrow

C,C++/C basic

[C 기초] 함수포인터

연잎(lotus leaf) 2021. 8. 31. 10:56
728x90

함수포인터란?


함수를 가리키는 포인터

 

 

사실 함수 이름은 포인터이므로 메모리주소가 담겨있다.

따라서 포인터에 함수의 주소를 저장하고 

그 함수포인터를 통해 인자로 함수를 주고받거나 호출할수있게된다.

 

 

 

1. 필요성

 

1) 함수자체의 매개변수, 반환값으로

 

: 여러사람이 협업할때에는, 누가 어떤 함수를 필요로 할지 모름. 그러나 함수포인터를 정의하고 매개변수로 전달하게 되면 그 함수 내부에서  호출이 가능하게 됨.

 

void func(void (*fp)()) {
      ...
     fp(); //함수포인터로 함수 호출
      ...
}

 

2) 배열요소로

 

3)구조체멤버로

 

:함수포인터를 구조체멤버로 넣고,  그 멤버함수를 추후에 사용자가 원하는대로 커스텀해서 구조체 특성에 맞는 함수를 대입시킬수있다. Java에서 메소드오버라이딩으로 각 객체의 특성에 맞는 함수를 정의할 수 있듯이, 

c에서도 함수포인터를 이용해 비슷하게 다형성을 구현하기 위한 방법으로 쓰일수 있다.

 

#include <stdio.h>

struct animal {

    char species;
    void (*walk)(); // 함수포인터를 구조체멤버로

};

void walk_dog() {

    printf("네발로 왈왈 짖으면서 뛰어다닌다.");

}

void walk_cat() {


    printf("요염하게 천천히 걷는다.");
}

int main()
{
    struct animal dog;
    struct animal cat;

    dog.walk = walk_dog;
    cat.species = walk_cat;

    dog.walk();
    cat.walk();


    return 0;
}

[결과]

 

 

 

2.  선언 및 초기화

 

반환값 자료형 (*함수포인터이름)(매개변수자료형); //매개변수이름은 생략할수있다.

 

 

:함수 포인터를 선언할 때는 함수 포인터와 저장될 함수의 반환값 자료형, 매개변수 자료형과 개수가 일치해야 한다.

반환값과 매개변수가 없을경우에는 void(*함수포인터이름)() 과 같은 형식을 취한다.

 

 

함수포인터이름 = 함수이름 // 함수포인터에 함수 저장

 

:위 식이 가능한 이유는 함수의 이름이 그 함수가 시작하는 주솟값을 담고있기때문이다.

 

 

그리고 함수호출은 일반 함수를 호출하는것 처럼

함수포인터이름 (전달할인자)  

로 호출해주면된다. 그럼 그 함수포인터안에 저장된 함수가 호출된다.

 

 int (*fp)(char, char);  //반환값 int 매개변수 char 두개인 함수 포인터 선언
 
 fp=function1; //함수포인터에 function1함수 저장. 
 fp(); //function1함수 호출

 

 

 

이때 , 이름에 꼭 괄호 () 를 쳐주어야 함수포인터임을 인식할수 있다.

ex) int *fp(char, char); (X)

    int (*fp)(char, char); (O)

 

 

<예시>

 

1) 반환값, 매개변수가 없는 함수포인터

 

#include <stdio.h>

void greeting()     // 반환값과 매개변수가 없음
{
    printf("안녕하세요. 연잎입니다!\n");
}

void greeting2(int old)    // 매개변수가 있음.
{
    printf("안녕하세요. %d살 연잎입니다!\n",old);
}

int main()
{
    void (*fp)();   // 반환값과 매개변수가 없는 함수 포인터 fp 선언. function pointer의 준말

    fp = greeting;     // greeting 함수의 메모리 주소를 함수 포인터 fp에 저장
    fp();           // 함수 포인터로 greeting 함수 호출

    fp = greeting2;   //  greeting2 함수의 메모리 주소를 함수 포인터 fp에 저장
    fp(21);           // 함수 포인터로 greeting2 함수 호출. 인자로 old를 건네줌.

    return 0;
}

[결과]

 

 

위 예제와 같이 함수포인터에는 어떤 함수가 저장되어있느냐에 따라 상황에 따라 함수를 바꾸어가며 호출할 수 있다.

 

 

2) 반환값, 매개변수가 있는 함수 포인터

 

#include <stdio.h>

// 덧셈 
int add(int a, int b)    //int형 매개변수 두 개 , int형 리턴
{
    return a + b;
}


int main()
{
    int (*fp)(int, int);    // int형 매개변수 두 개 , int을 리턴하는 함수 포인터 fp 선언

    fp = add;                      // add 함수의 메모리 주소를 함수 포인터 fp에 저장
    printf("%d\n", fp(15, 35));    // 50: 함수 포인터로 add 함수를 호출하여 합을 구함

    return 0;
}

 

 

 

 

 

 

 

 

 

'C,C++ > C basic' 카테고리의 다른 글

[C 기초] 구조체포인터  (0) 2021.08.29
[C 기초 ] 동적할당 (malloc,memset)  (0) 2021.08.26
[C 기초] 구조체  (0) 2021.08.24