-
[C Language] 42. void형 포인터 - C 언어CSE/C Language 2015. 8. 5. 14:33
1. void 형 포인터란?
널 포인터가 포인터임에도 불구하고 어느 곳도 가리키고 있지 않는 데 반해, void 형 포인터는 무엇이든 가리킬 수 있는 포인터이다.
널 포인터가 아무것도 넣을 수 없는 자루라면 void 형 포인터는 무엇이든 들어가는 자루이다.
void 형 포인터는 현재 가리키고 있는 대상체가 정해져 있지 않는 포인터이다.
바꾸어 말하면 현재 가리키는 대상체가 정해져 있지 않기 때문에 대상체만 정해지면 얼마든지 사용할 수 있다는 의미이다.
2. void 형 포인터 변수 정의
char 형 포인터는 'char *' 로 표기할 수 있고 int 형 포인터는 'int *'로 표기할 수 있다. 마찬가지로 void 형 포인터는 'void *'로 표기한다.
void *void_p;
void_p는 포인터 변수이기 때문에 당연히 메모리에 4 바이트가 할당된다. 또한, 포인터 변수이기 때문에 주소 값 이외에는 할당될 수 없다. 그렇다면 void_p가 가리키는 값은 어떤 형일까?
지금까지는 포인터 변수를 정의할 때 포인터 변수 앞에 형을 지정함으로써 형을 명시했다.
void 형 포인터 변수는 정의할 때 아무것도 가리키고 있지 않다는 의미로 'void *'로 지정했기 때문에 현재는 무엇을 가르키고 있는지 알 수 없다. void 형 포인터 변수를 사용할 때 포인터 변수가 가리킬 형이 프로그램을 진행하면서 정해지는 이유가 이것 때문이다.
3. void 형 포인터의 성질
void 형 포인터는 다음과 같은 성질이 있다.
- 어떠한 형 변환(cast 연산자) 없이도 void 형 포인터 변수에 주소 값을 할당할 수 있다.
- void 형 포인터 변수에서 값을 읽을 때는 반드시 캐스트 연산자를 사용해야 한다.
- '*' 연산자(간접 지정 연산자)를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.
- void 형 포인터 변수에 ++, --를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.
위의 void 형 포인터 변수 성질들은 원리만 알면 너무도 당연한 내용이므로 굳이 외우려고 할 필요가 없다.- 어떠한 형 변환(cast 연산자) 없이도 void 형 포인터 변수에 주소 값을 할당할 수 있다.
12345678910111213141516171819202122232425/** voidp.c** Created on: 2015. 8. 5.* Author: Yeonsu*/#include <stdio.h>int main(void) {int num = 123;float num_f = 56.6;char text_c = 'M';void *void_p;void_p = #void_p = &num_f;void_p = &text_c;return 0;}cs 컴파일을 해보면 에러가 발생하지 않는다. 위의 예제로 확인할 수 있는 것은 void 형 포인터 변수에 주소 값을 대입할 때는 어떠한 형 변환도 필요없다는 것이다.
- void 형 포인터 변수에서 값을 읽을 때는 반드시 캐스트 연산자를 사용해야 한다.
여러분이 다른 사람의 집을 방문했다고 가정해 보자. 닭고기가 너무 먹고 싶어서 냉장고 문을 열었다. 100% 닭고기를 냉장고에서 꺼낼 수 있는 경우는 여러분이 닭고기를 넣은경우와 다른 사람이 닭고기 넣는 것을 본 경우이다.
void 형 포인터 변수도 마찬가지다. void 형 포인터가 냉장고라 할 때 그곳에서 int 형을 꺼내려고 한다면 그곳에 여러분이 int형을 넣든지 넣은 것을 본 경우이다. 프로그램은 다른 사람이 대신 작성해 주는 것이 아니므로 전자가 이에 해당된다. 결론을 말하면 void 형 포인터 변수에서 무언가를 꺼내려고 한다면 그 안에 무엇이 들어 있는지 미리 알아야 한다는 것이다. void 형 포인터 변수에 무엇이 들어 있는지 모르는 상태에서 무조건 꺼내려고 한다면 원하지 않는 결과를 얻을 것이다.
123456789101112131415161718192021222324252627282930/** voidp.c** Created on: 2015. 8. 5.* Author: Yeonsu*/#include <stdio.h>int main(void) {int num = 123;float num_f = 56.6;char text_c = 'M';void *void_p;void_p = #printf("int %d\n", *((int *) void_p));void_p = &num_f;printf("float %f\n", *((float *) void_p));void_p = &text_c;printf("char %c\n", *((char *) void_p));return 0;}cs - '*' 연산자(간접 지정 연산자)를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.
포인터 변수에 '*' 연산자를 사용한다는 의미는 포인터 변수에 할당된 주소를 참조하여 값을 구하는 것이다. 값을 구하려면 그 값이 int 형인지 double 형인지 알아야 주소 값에서 4, 8 바이트를 읽어 올 수 있다. 그러므로 void 형 포인터에서 '*' 연산자를 사용할 때는 항상 캐스트 연산자가 필요하다. 바로 전 예제를 보면 int 형 123을 얻기 위해 '*'를 사용했고 '*'를 사용하기 위해서 캐스트 연산자가 사용되었다. 캐스트 연산자를 사용하지 않으면 주소가 가리키는 곳에서부터 몇 바이트를 읽어 올지 알 수 없으므로 void 형 포인터에서 값을 취할 때는 캐스트 연산자가 반드시 필요하다.
- void 형 포인터 변수에 ++, --를 사용할 때는 항상 캐스트 연산자를 사용해야 한다.
++ 이나 -- 의 의미는 x = x + 1 이나 x = x - 1과 같은 수식을 줄여서 사용한 것이다. x = x + 1을 사용하려면 x 에서 값을 구하고 여기서 1 을 더한 후 다시 x 에 넣어야 한다. x 에서 값을 구하려면 형이 정해져야 하고 형이 정해지기 위해서는 캐스트 연산자의 사용이 필수적인 것이다.'CSE > C Language' 카테고리의 다른 글
[C Language] 이클립스 C/C++ 개발 환경 구축 !! (0) 2015.09.16 [C Language] 43. 포인터 - 매개변수 처리 총정리 (0) 2015.08.10 [C Language] 41. 포인터의 개념을 깨는 '0' (0) 2015.08.05 [C Language] 40. 문자열 함수 - C 언어 (0) 2015.08.05 [C Language] 39. 포인터의 포인터 - C 언어 (0) 2015.08.05 [C Language] 38. 문자열과 포인터 - C 언어 (0) 2015.08.04