
1. 포인터의 포인터에 대한 이해
포인터의 포인터는 포인터 변수를 가리키는 또 다른 포인터 변수를 뜻하는 것으로서 흔히 '이중 포인터' 또는 '더블 포인터'라 부르며, 다음과 같이 포인터 변수의 선언에 사용되는 *연산자를 두 개 이어서 선언한다.
int ** dptr
포인터 변수는 종류에 상관없이 무조건 주소 값을 저장하는 변수이다.
다만 차이가 나는 것은 포인터 변수가 가리키는 대상일 뿐이다.
그럼 이와 관련해서 다음 코드를 보자.
int main(void)
{
double num=3.14;
double* ptr=#
...
}
위의 코드에서 변수 num과 포인터 변수 ptr의 차이점과 공통점을 정리해보자.
- 공통점: 둘 다 변수이다. 따라서 값의 저장이 가능하다.
- 차이점: 저장하는 값의 종류(유형)이 다르다.
이렇듯 ptr도 메모리 공간에 할당이 되는 변수이다.
따라서 이 ptr을 대상으로도 &연산이 가능하며, 이때 반환되는 주소 값은 'double형 더블 포인터 변수'에 저장이 가능하다.
때문에 싱글 포인터 변수 ptr을 대상으로 다음과 같은 문장의 구성이 가능하다.
double** dptr=&ptr;
이렇게 선언된 상태에서, dptr을 대상으로 다음과 같은 방식으로 포인터 변수 ptr과 변수 num에 접근이 가능하다.
*dptr=...;
*dptr은 포인터 변수 ptr을 의미한다.
*(*dptr)=...;
*(*dptr)은 변수 num을 의미한다.
그리고 *(*dptr)에서 괄호는 생략이 가능하기 때문에 **dptr로표현이 가능하며, 이것이 보다 일반적인 표현이다.
포인터 변수에 저장된 값을 Swap하려면
void Swap(int** dptr1, int** dptr2)
{
int* temp = *dptr1;
*dptr1 = * dptr2;
*dptr2 = temp;
}
int main(void)
{
int num1=10, num2=20;
int* ptr1=&num1;
int* ptr2=&num2;
printf("%d, %d", *ptr1, *ptr1); // 10, 20 출력
Swap(&ptr1, &ptr2);
printf("%d, %d", *ptr1, *ptr2); // 20, 10 출력
return 0;
}
#include <stdio.h>
int main(void)
{
int num1=10, num2=20, num3=30;
int* ptr1=&num1;
int* ptr2=&num2;
int* ptr3=&num3;
int* ptrArr[]={ptr1, ptr2, ptr3};
int** dptr=ptrArr;
printf("%d %d %d \n", *ptrArr[0], *ptrArr[1], *ptrArr[2]); // 10 20 30 출력
printf("%d %d %d \n", *dptr[0], *dptr[1], *dptr[2]); // 10 20 30 출력
return 0;
}
2. 다중 포인터 변수와 포인터의 필요성
int num=10;
int* ptr=#
int** dptr=&ptr;
int*** tptr=&dptr;
다중 포인터가 사용되는 예는 그리 많지 않다.
자료구조와 알고리즘을 공부하게 되면 포인터의 필요성을 보다 확실히 느끼고 알 수 있게 된다.