Const void 포인터 - Const void pointeo

함수 역시 함수의 주소 값을 저장할 수 있는 포인터 변수를 선언할 수 있다. 그렇다면 어떻게 선언해야 할까? 먼저 다음의 예시를 살펴보자.

<소스코드>

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)(intint= TwoAdderFunc; // TwoAdderFunc 함수 포인터

void (*fptr2) (const char*= ShowString; // ShowString 함수 포인터

// 함수 포인터를 통한 호출

fptr1(n1, n2);

fptr2(str);

return 0;

cs

<실행결과>

Const void 포인터 - Const void pointeo

매개변수의 선언으로도 함수 포인터가 올 수 있다. 먼저 이를 예시로 알아보자.

<소스코드>

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

<실행결과>

Const void 포인터 - Const void pointeo

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 = &num; // void형 포인터에 int형 주소 값 저장

printf("%p \n", ptr);

ptr = Func; // void형 포인터에 Func함수 주소 값 저장

printf("%p \n", ptr);

return 0;

}

cs

<실행결과>

Const void 포인터 - Const void pointeo

이렇듯 void 형 포인터의 경우 어떤 형의 주소 값이든 담을 수 있다는 장점이 있지만 연산, 변경, 참조를 할 수 없다는 단점이 존재한다.

(위 포스팅은 윤성우 님의 열혈 C를 인용하였습니다.)