[cpp] 복잡한 포인터 선언 이해하기

@codemaru · August 07, 2007 · 5 min read

C언어 게시판에 자주 올라오는 질문 중에 하나가 복잡한 포인터 선언문을 해석하는 것들이다. 대부분의 학생들은 이것을 막연히 외우려고 한다. int *a[3]은 int 포인터를 저장하는 배열이고, int (*a)[3]은 int 배열에 대한 포인터라고 외우는 것이다. 하지만 이렇게 외운 지식은 그 형태가 조금만 달라져도 무용지물이 된다. 그렇다면 어떻게 해야 이러한 선언문을 손쉽게 해석할 수 있을까? 간단한 규칙만 이해하면 된다.

복잡한 선언을 정확하게 이해하기 위한 첫 단계는 선언문 내부에 나타나는 각 요소의 정확한 의미를 이해하는 것이다. <표 1>에는 선언문 내부에 나타나는 각 구성요소의 의미와 사용 예가 나와있다. 선언문을 해석할 때 영어를 이용하면 굉장히 편리하게 해석할 수 있다. 따라서 각 기호에 맞는 영어 표현도 같이 알아두는 것이 좋다.

표 1 표현식에 나타나는 기호들의 의미

기호 표현 의미
* pointer to 특정 대상체를 가리키는 포인터 int *a;
a는 int 형을 가리키는
포인터다.
[] array of 특정 대상체를 저장하는 배열 int a[3];
a는 int를 3개 저장할 수 있는 배열이다.
() function 인자를 받고 값을 리턴하는 함수 int a();
a는 인자가 없고 int를
반환하는 함수다.

다음으로 이해해야 하는 것은 선언문을 해석하는 순서다. 선언문은 선언 대상이 되는 변수 명에서 시작해서 오른쪽으로 가면서 해석한다. 선언문의 끝이나 오른쪽 괄호를 만나면 방향을 바꾸어 왼쪽으로 가면서 해석한다. 왼쪽으로 가면서 해석을 하다 왼쪽 괄호를 만나면 다시 오른쪽으로 가면서 해석한다. 이렇게 해서 선언문의 가장 왼쪽 끝에 도달하면 해석이 마무리 된다.

표 2 복잡한 표현식들의 해석 순서와 해석 결과

표현식 해석 순서
해석 결과
int **a;
  a => a; => *a; => **a; => int
**a;
a is a pointer to pointer to int
a는 int를 가리키는
포인터의 포인터다.
int *a[3];
  a => a[3] => a[3]; => *a[3];
=> int *a[3];
a is an array of 3 pointer to int
a는 int를 가리키는
포인터를 세 개 저장하는 배열이다.
int (*a)[3];
  a => a) => (*a) => (*a)[3] =>
int (*a)[3]
a is a pointer to array of 3 int
a는 int 세 개를
저장하고 있는 배열을 가리키는 포인터다.
int *(*(*fp1)(int))[10]; fp1 => fp1) => (*fp1) =>
(*fp1)(int) => (*fp1)(int)) => (*(*fp1)(int)) => (*(*fp1)(int))[10]
=> *(*(*fp1)(int))[10]; = > int *(*(*fp1)(int))[10];
fp1 is a pointer to function that takes
an int as an argument and returns a pointer to an array of 10 pointers to
ints.
fp1은 int를 인자로
받고 int에 대한 포인터를 열 개 저장하는 배열을 가리키는 포인터를 리턴하는 함수에 대한 포인터다.
char *(*(**foo[][8])())[]; foo[] => foo[][8] => *foo[][8]
=> (**foo[][8]) => (**foo[][8])() => *(**foo[][8])() =>
(*(**foo[][8])())[] => char *(*(**foo[][8])())[]
foo is an array of array of 8 pointers to
pointer to function that returns a pointer to array of pointer to char.
foo는 char를
가리키는 포인터를 저장하는 배열을 가리키는 포인터를 리턴하는 함수에 대한 포인터를 가리키는 포인터를 8개
저장할 수 있는 배열에 대한 배열이다.
@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중