C 언어에서 이중 포인터(double pointer)는 다른 포인터 변수의 주소값을 저장하는 변수를 의미합니다. 즉, '포인터를 가리키는 포인터'라고 이해할 수 있습니다.
이중 포인터(Pointer to Pointer)란?
이중 포인터는 다음과 같은 형식으로 선언합니다.
데이터타입 ** 포인터이름;
예를 들어 int **p;라고 선언하면, p는 int형 변수를 가리키는 포인터의 주소를 저장하는 이중 포인터가 됩니다.
초기화
이중 포인터는 주소 연산자 &를 사용하여 초기화합니다.
int a = 10; int *p; int **q; p = &a; // p는 변수 a의 주소를 저장 q = &p; // q는 포인터 p의 주소를 저장
값 접근하기
역참조 연산자(indirection operator) *를 사용하여 값에 접근합니다. 일반 포인터는 *를 한 번, 이중 포인터는 *를 두 번 사용하여 원래 변수의 값에 도달합니다.
예제 코드
다음은 이중 포인터의 동작을 보여주는 C 프로그램입니다.
#include<stdio.h>
main ( ){
int A = 10;
int *p;
int **q;
p = &A;
q = &p;
printf("A =%d",A);
printf("포인터로 접근한 A의 값 = %d", *p);
printf("이중 포인터로 접근한 A의 값 = %d", **q);
}실행 결과
위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
A=10 포인터로 접근한 A의 값 = 10 이중 포인터로 접근한 A의 값 = 10
변수 A, 포인터 p, 이중 포인터 q 모두 결국 같은 메모리 위치를 참조하므로 동일한 값 10이 출력되는 것을 확인할 수 있습니다.
void 포인터(Void Pointer)란?
void 포인터는 어떤 데이터 타입의 변수 주소든 저장할 수 있는 범용 포인터입니다. 즉, int, float, char 등 어떤 자료형의 변수든 가리킬 수 있다는 것이 가장 큰 특징입니다.
void 포인터는 다음과 같이 선언합니다.
void *포인터이름;
예를 들어 void *vp;와 같이 선언할 수 있습니다.
값 접근하기
void 포인터에는 자료형 정보가 없기 때문에, 값을 읽어오려면 반드시 타입 캐스트(type cast) 연산자를 사용해야 합니다. 문법은 다음과 같습니다.
* ((타입캐스트) void 포인터)
사용 예시는 다음과 같습니다.
int i=10;
void *vp;
vp = &i;
printf ("%d", * ((int*) vp)); // int형으로 타입 캐스트 후 역참조예제 코드
다음은 void 포인터가 서로 다른 자료형의 변수를 가리키는 것을 보여주는 C 프로그램입니다.
#include<stdio.h>
main ( ){
int i =10;
float f = 5.34;
void *vp;
clrscr ( );
vp = &i;
printf ("i = %d", * ((int*)vp));
vp = &f;
printf ( "f = %f", * ((float*) vp));
getch ( );
}실행 결과
위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
i = 10 f = 5.34
같은 void 포인터 vp가 int형 변수와 float형 변수를 번갈아 가리키면서, 각각 올바른 타입으로 캐스팅하여 값을 출력하는 것을 확인할 수 있습니다.
정리
이중 포인터는 포인터의 주소를 저장하여 다단계 간접 참조를 가능하게 하며, void 포인터는 자료형에 제약 없이 모든 타입의 주소를 저장할 수 있는 유연성을 제공합니다. 단, void 포인터를 사용할 때는 반드시 적절한 타입 캐스트가 필요하다는 점을 기억해야 합니다.