함수 역시 함수의 주소 값을 저장할 수 있는 포인터 변수를 선언할 수 있다. 그렇다면 어떻게 선언해야 할까? 먼저 다음의 예시를 살펴보자.
<소스코드>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int SimpleFunc(int num) {
return num;
}
int main(void) {
int num;
scanf("%d", &num);
printf("%d을 입력받았습니다.\n", SimpleFunc(num));
return 0;
}
|
cs |
위의 SimpleFunc 함수를 보면 다음의 사실들을 알 수 있다.
함수의 반환형 : int형
함수의 매개변수 : int형 1개
즉 우리는 함수의 포인터를 선언하기 위해서 함수 포인터의 변수에는 반환형 정보와, 매개변수 선언의 정보를 모두 표시해야 한다. 따라서 함수 포인터 변수는 다음과 같다. int (*fptr) (int) 여기서 fptr은 포인터, 앞의 int는 반환형, 뒤의 int는 매개변수의 형과 그 개수를 의미한다. 이를 예시로 확인해보면 int TwoSimpleFunc(int num1, int num2) 인 경우 위의 규칙을 적용하면 함수의 포인터 변수는 다음과 같다.
int (*fptr) (int, int);
이 포인터 변수에 TwoSimpleFunc의 주소 값을 저장하는 대입연산은 다음과 같다.
fptr = TwoSimpleFunc;
또한 이 포인터 변수 fptr을 이용해서 fptr(1, 2); 의 형태로도 함수를 호출할 수 있다. -> TwoSimpleFunc(1, 2);와 같은 결과. 예시를 통해 알아보자.
<소스코드>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void TwoAdderFunc(int num1, int num2) {
int result = 0;
result = num1 + num2;
printf("%d 와 %d 의 합은 %d 입니다.\n", num1, num2, result);
}
void ShowString(const char* str) {
printf("%s", str);
}
int main(void) {
int n1, n2;
scanf("%d %d", &n1, &n2);
const char* str = "함수 포인터";
void (*fptr1)(int, int) = TwoAdderFunc; // TwoAdderFunc 함수 포인터
void (*fptr2) (const char*) = ShowString; // ShowString 함수 포인터
// 함수 포인터를 통한 호출
fptr1(n1, n2);
fptr2(str);
return 0;
}
|
cs |
<실행결과>
매개변수의 선언으로도 함수 포인터가 올 수 있다. 먼저 이를 예시로 알아보자.
<소스코드>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#include <stdio.h>
int WhoIsFirst(int age1, int age2, int (*fptr) (int n1, int n2)) { // 매개변수로 함수 포인터가 있음
return fptr(age1, age2); // 함수 포인터로 함수 호출
}
int OlderFirst(int age1, int age2) { // 나이가 많은 사람 먼저 하는 함수
if (age1 > age2)
return age1;
else if (age1 < age2)
return age2;
else
return 0;
}
int YongerFirst(int age1, int age2) { // 나이가 적은 사람 먼저 하는 함수
if (age1 < age2)
return age1;
else if (age1 > age2)
return age2;
else
return 0;
}
int main(void) {
int age1 = 10, age2 = 20;
int first;
printf("입장방법 : OlderFirst \n");
first = WhoIsFirst(age1, age2, OlderFirst); // WhoIsFirst 함수 호출 매개변수로 OlderFirst 함수 넘김
printf("%d세와 %d세 중 %d세가 먼저 입장! \n\n", age1, age2, first);
printf("입장방법 : YongerFirst\n");
first = WhoIsFirst(age1, age2, YongerFirst); // WhoIsFirst 함수 호출 매개변수로 YongerFirst 함수 넘김
printf("%d세와 %d세 중 %d세가 먼저 입장! \n\n", age1, age2, first);
return 0;
}
|
cs |
<실행결과>
void 포인터
void * ptr; 의 경우 void형 이므로 형이 정해지지 않은 즉 어떤 형태의 주소 값이든 저장할 수 있는 포인터 변수이다.
이를 다음의 예시를 통해 알아보자.
<소스코드>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <stdio.h>
void Func(void) {
printf("그냥 함수");
}
int main(void) {
void* ptr; // void형 포인터
int num = 20;
ptr = # // void형 포인터에 int형 주소 값 저장
printf("%p \n", ptr);
ptr = Func; // void형 포인터에 Func함수 주소 값 저장
printf("%p \n", ptr);
return 0;
}
|
cs |
<실행결과>
이렇듯 void 형 포인터의 경우 어떤 형의 주소 값이든 담을 수 있다는 장점이 있지만 연산, 변경, 참조를 할 수 없다는 단점이 존재한다.
(위 포스팅은 윤성우 님의 열혈 C를 인용하였습니다.)
'C' 카테고리의 다른 글
11. 구조체와 사용자 정의 자료형 (0) | 2021.06.27 |
---|---|
10. 문자열 관련 함수 (0) | 2021.06.27 |
8. 2차원 배열과 포인터 (0) | 2021.06.26 |
7. 이중 포인터 (0) | 2021.06.25 |
6. 다차원 배열 (0) | 2021.06.25 |