안녕하세요! 5기 gulee입니다.
함수 포인터에 관해 여러가지 의견들도 많이 듣고 CS 공부를 해보면서 느낀 함수포인터에 관해 기초 개념정리를 하고자 해서 이렇게 글을 작성하게 됬습니다!
1. 함수 호출 방법
•
어떤 함수를 호출할 때는 직접 함수명을 씀
result = sum(op1, op2);
C
복사
•
위의 코드를 어셈블리어로 보게 된다면
00E211A6 call sub (0E21040h)
C
복사
어셈블리어로 보면 함수를 호출할때 그 함수의 첫 시작 주소를 받는다
그래서 함수를 호출한다는 것 자체가 ‘모든 데이터가 준비가 됐으면 나는 어떤 메모리 주소로 점프를 해서 거기서 코드를 실행할 게’ 라는 뜻이다
실행을 하다가 return 을 만나면 다시 어떤 메모리 주소로 점프를 한다는 뜻이다
•
함수의 주소 이 주소는 컴파일하는 도중에 이미 정해지는 거다. 실행 중에 바뀌는 주소는 아니였다
•
실행 중에 다른 코드로 이동하는 경우
◦
실행 도중에 다음에 실행할 코드 위치를 찾아가는 경우도 있다
◦
함수에서 반환할 때 돌아가야 하는 호출자 코드의 주소로 찾아간다
◦
돌아갈 주소는 스택 메모리에 저장되어 있다
◦
돌아갈 주소가 스택에 들어있단 의미는?
▪
실행 도중에 결정된다
•
즉, 모든 것이 다 메모리 주소이다
◦
그럼 실행 도중 조건에 따라 어떤 함수를 실행해주려면 무슨 주소를 변수에 기억하고 있어야 하는거지? → 그 함수의 시작 주소
◦
실제 이렇게 어셈블리 보면 모든 코드 앞에 메모리 주소가 있고 함수의 시작 코드도 마찬가지로 시작 주소가 있다
2. 함수 포인터는?
•
함수 포인터는?
◦
함수 포인터는 실제로 그 함수의 시작주소를 저장하고 있는 포인터라고 생각하면 된다
◦
여기서 시작 주소는 우리가 컴파일하는 도중에 이미 정해져있다고, 위에서 들어 알고 있다
•
쉽게 말해서 함수 포인터도 어떤 메모리의 시작 주소를 저장하는 포인터이고, 우리가 익히 알고 있는 포인터의 개념과 똑같다고 볼 수 있다
3. 선언과 사용
<반환형> (*<변수명>)(<매개변수 목록>);
•
함수의 시작 주소를 저장하는 변수
•
함수의 매개변수 목록과 반환형을 반드시 표기해야 함
함수 포인터 변수의 선언과 사용
int sum(int op1, int op2)
{
return op1 + op2;
}
C
복사
int result = 0;
int op1 = 10;
int op2 = 20;
int (*func)(int, int) = sum;
result = func(op1, op2);
C
복사
func는 변수 이름 func라는 변수는 포인터를 가지고 있는데 그 포인터 안에는 함수의 시작주소가 저장되어 있다.
함수 포인터 매개변수의 선언과 사용
int sum(int op1, int op2)
{
return op1 + op2;
}
int pow(int op1, int op2, int (*f)(int, int))
{
int op3 = f(op1, op2);
return op1 * op2 * op3;
}
C
복사
int result = 0;
int op1 = 10;
int op2 = 20;
result = pow(op1, op2, sum);
C
복사
•
함수 pow() 는
◦
매개변수가 총 3개
1.
int 형
2.
int 형
3.
함수 포인터
a.
두 개의 int형 매개변수를 받고 int 형을 반환하는 함수를 가리킴
◦
반환형은 int 형
함수 포인터의 다른 사용 예
int sum(int op1, int op2)
{
return op1 + op2;
}
C
복사
int (*func)(int)(int) = sum;
C
복사
•
뒤에 sum이라는 함수명을 쓰면 함수 포인터가 그 함수의 시작주소의 값을 가지고 있게 된다
•
만약 같은 매개변수를 받는 함수가 있다면 그 함수 이름으로 바꿔서 사용 할 수 있다
#include <stdio.h>
int func_sum(int op1, int op2)
{
return op1 + op2;
}
int func_pow(int op1, int op2)
{
return op1 * op2;
}
int main(void)
{
int result = 0;
int (*func)(int, int) = func_sum;
int op1 = 2;
int op2 = 5;
result = func_sum(op1, op2);
printf("func sum : %d\n", result);
func = func_pow;
result = func(op1, op2);
printf("func pow : %d\n", result);
}
C
복사
4. 함수 포인터 읽는 방법, 오른쪽-왼쪽 규칙 (Right-Left Rule)
함수 포인터 읽는 방법
•
오른쪽-왼쪽 규칙 (Right-Left Rule)이라고 함
int (*func)(int, int)
C
복사
변수 func는 두 개의 int 형 매개변수를 받고 int형을 반환하는 함수의 포인터이다. 라는 뜻이다
void (*func)(int)
C
복사
변수 func는 한개의 int 형 매개변수를 받고 반환값이 없는 함수 포인터이다.