본문 바로가기

프로그래밍/C 기초

[C언어 강좌] #48 함수 포인터

제목에서도 알 수 있듯이 이번 주제는 함수 포인터입니다.

함수 포인터라는 이름만 들어도 딱 감이 오시겠지만, 함수포인터는 함수를 가리키는 포인터입니다.


변수만 메모리 공간에 저장되는 게 아니고 함수도 메모리 공간에 저장돼서 호출 시 실행이 됩니다.

그렇다면 함수도 메모리 공간에 있으니 당연히 메모리 주소도 존재한다는 뜻이겠죠?


배열의 이름이 배열의 시작주소 값을 나타내는 것 처럼 함수의 이름도 메모리 공간의 주소를 나타냅니다.


1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
 
int add(int a,int b) {
    return a+b;
}
int main (void) {
    printf("%d",add);
}
cs




두 변수를 더해서 값을 반환하는 add함수를 만들고 함수명을 적어서 출력해봤습니다.

출력결과는 add함수의 주소 값이 출력되었습니다.


이 주소값은 add함수의 시작 주소값입니다.




만약 add함수의 주소가 0x04AB6B라고 했을때

add(10, 20)으로 함수를 호출하면 0x04AB6B에 접근해서 해당 함수를 실행합니다.




그리고 이 함수의 주소를 가리킬수 있는 포인터 변수가 함수 포인터입니다.


포인터 함수의 포인터 형은 함수의 반환형과 매개변수 형태에 따라 결정해주시면 됩니다.



1
2
3
4
int add(int a,int b) {
    return a+b;
}
 
cs

이 add함수를 가리키는 포인터 변수 선언으로 예를 들어봅시다.




add함수의 반환형이 int이고 매개변수로 int형 변수를 두개 선언했기 때문에 위와 같이 선언해주면 됩니다.


1
int (*funp)(int,int= add;
cs

그리고 함수명을 적어서 함수의 주소값을 대입해주면 add함수를 가르키는 함수 포인터 funp 가 선언됩니다.








함수 포인터도 자신이 저장해놓은 함수와 똑같이 호출 가능합니다.

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
 
 
int add(int a,int b) {
    return a+b;
}
int main (void) {
    int (*funp)(int,int= add;
    printf("%d",funp(50,30));
}
 
cs

출력결과





이 예제를 보면 add함수를 가리키고있는 포인터 함수 funp도 함수처럼 호출 가능하다는것을 알수 있습니다. 





add함수와 funp가 가르키고 있는 주소의 값은 같기 때문에 funp를 실행하면 add함수의 시작번지 주소값으로 이동하여 실행합니다.

그래서 add함수와 funp 함수 포인터는 똑같이 사용 가능합니다.


배열의 이름이 배열의 시작 주소값을 가르키고 있듯이 함수도 함수의 시작 주소값을 가르키고 있는것입니다.




그리고 함수포인터를 사용하는 간단한 예제를 보여드리겠습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
 
 
int add(int a,int b) {
    return a+b;
}
int sub(int a,int b) {
    return a-b;
}
int main (void) {
    int (*funp)(int,int= NULL;
    int num1, num2;
    scanf("%d %d"&num1, &num2);
    
    if(num1 <  num2)
        funp = add;
    else
        funp = sub;
 
    printf("%d",funp(num1,num2));
}
 
cs

num1이 num2보다 작을때는 더하고 클때는 빼서 출력하는 코드입니다.

사실 실용성이 있는 프로그램은 아니지만 이런식으로 상황에따라서 실행하는 함수가 다르게 만들수 있습니다.


이 코드는 굳이 포인터함수를 모르더라도 충분히 구현 가능한 간단한 코드입니다.

그냥 이런식 으로 사용 가능하다는 것을 보여드린 것 입니다.