이중 포인터
먼저 잘 알고 있는 포인터를 하나만 쓴 경우를 보자.
int main() { int n = 10; int *p = &n; printf("%d\n", n); // 10 printf("%d\n", *p); // 10 printf("%d\n", &n); // 5634240 printf("%d\n", p); // 5634240 printf("%d\n", &p); // 5634228 }
정수 변수를 포인터로 가리킬 때의 상황을 그리면 포인터 변수 p에 n의 주소가 들어있는 것을 알 수 있다.
그래서 간접지정 연산자(*)로 역참조하면(*p) n이 가지고 있는 값 10을 쓸 수 있다.
이번엔 정수 변수를 가리키는 포인터 변수를 가리키는 포인터 변수를 만들어보자.
int main() { int n = 10; int *p = &n; int **p2 = &p; printf("%d\n", n); // 10 printf("%d\n", *p); // 10 printf("%d\n", **p2);//10 printf("%d\n", &n); // 8218548 printf("%d\n", p); // 8218548 printf("%d\n", *p2);// 8218548 printf("%d\n", &p); // 8218536 printf("%d\n", p2); // 8218536 printf("%d\n", &p2);// 8218524 }
&n = p = *p2임을 알 수 있다. 당연하다. p의 주소를 가지고 포인터 변수 p2를 초기화했기 때문이다.
int **p2를 뒤부터 해석해보자.
- p2 : 라는 이름의 변수는
- * : 포인터 변수이고
- int * : 가리키는 대상은 정수를 가리키는 포인터이다.
만약 int *p2 = &p로 쓴다면? p가 포인터 변수이지만 int *p2 = &p를 쓴다고 컴파일 오류가 나진 않는다.
다만 당연하게도 **p2로 n의 값을 사용할 수 없다.