복잡한 포인터 선언 이해하기 :: 2007/08/07 21:18



신입 개발자를 위한
복잡한 포인터 선언을 해석하는 방법
신영진 pop@jiniya.net http://www.jiniya.net

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개 저장할 수 있는 배열에 대한 배열이다.


스폰서
글타래

  • 2주간 인기 글
  • 2주간 인기글이 없습니다.
Trackback Address :: http://jiniya.net/tt/trackback/555
  • 장난꾸러기 포인터 이해...

    Tracked from microDev before wideDev | 2007/08/08 10:57 | DEL

    까칠한 포인터--;; 사실 실무에서는 여러 이유에서 3중 포인터등 복잡한 포인터 선언을 거의 쓰지 않는것으로 알고있다..(아님 말고) 그래도 가끔,,,, 오픈 소스를 보다보면 포인터로 장난(?)을 ..

  • 쉴때 읽으면 좋은 포인터 읽기(?)

    Tracked from Lamen's Story ## | 2009/06/10 09:43 | DEL

    int *foo 의 의미는?그러면, int **foo; 의 의미는?그러면,int *a[3]; 의 의미는?그러면,int (*a)[3]; 의 의미는??그러면, 더 복잡한 char *(*(**foo[][8])())[]; 의미는??실제로 얼마나 저렇게 많은 포인트를 쓰면..

  • Gravatar Image.
    라디앙 | 2007/08/08 16:02 | PERMALINK | EDIT/DEL | REPLY

    아아.. 역시 포인터는 어렵습니다. ㅠ.ㅠ
    그래도 좋은글 올려주셔서 감사드립니다.

    • Gravatar Image.
      codewiz | 2007/08/09 12:51 | PERMALINK | EDIT/DEL

      쓰다보면 익숙해질 거예요. 너무 걱정하지 마세요. ㅎㅎ
      그리고 사실 저렇게 복잡한 포인터 식을 실제로 사용하는 일은 거거거의 없습니다.

  • Gravatar Image.
    고어핀드 | 2007/08/21 11:25 | PERMALINK | EDIT/DEL | REPLY

    오오.. 정말 이렇게 읽으면 되는군요. 전 지금까지 하나씩 괄호 쳐가면서 읽었답니다. 어째 stack이 떠오르는 멋진 해법이네요. 그런데 직접 따라서 해보다 보니 영어로 해석한 뒤 읽는 게 처음부터 한국어로 읽는 것보다 편해 보이네요?

    • Gravatar Image.
      codewiz | 2007/08/22 00:48 | PERMALINK | EDIT/DEL

      네 영어 해석 다음에 한글로 이해하는게 편하답니다. 그런데 몇 번 해보면 굳이 해석하지 않아도 이해가 될겁니다.

  • Gravatar Image.
    Ronie.Kang | 2007/09/13 17:39 | PERMALINK | EDIT/DEL | REPLY

    좋은 정보 감사 합니다.

    좌우 우좌로 해석 하는 방법을 알게 되니
    의미를 쉽게 파악 할 수 있군요.!!!!

    복잡한 포인터의 개념을 아주 쉽게 정리 해주셨네요 감사 합니다.

    • Gravatar Image.
      codewiz | 2007/09/14 16:31 | PERMALINK | EDIT/DEL

      도움 되셨다니 저도 기분 좋네요.
      자주 놀러와 주세용 ^^

  • Gravatar Image.
    glukjeoluk | 2007/10/15 20:55 | PERMALINK | EDIT/DEL | REPLY

    긁어 갈께요...^^
    좋은 자료 열씨미 보구 있어요...^^

  • Gravatar Image.
    아 멋져요 ㅎ | 2008/04/16 00:46 | PERMALINK | EDIT/DEL | REPLY

    ㅎㅎ 위 포인터 선언에 대한 글 읽고, 홈페이지 찾아왔는데 ㅋ
    엄청고수시네요 후아~
    "The art of Computer Virus Research and Defense" 이책도 정말 읽고싶은데..
    기반지식과 무엇보다 영어가 안되는... 흑..
    열심히 공부해야겠습니다..

  • Gravatar Image.
    Ronie.Kang | 2008/06/30 17:45 | PERMALINK | EDIT/DEL | REPLY

    작년 독일에서 너무 무료한 시간을 ... 보내다
    신영진님 싸이트를 알게 되어서 많이 즐거웠습니다.

    올해 다시 찾아 뵙네요. 좋은글 담아 갑니다.

    고운 하루 되세요~~
    아 이글루스에서 티스토리로 갈아 탔습니다.
    ^^

  • Gravatar Image.
    공돌이pooh | 2010/07/07 03:05 | PERMALINK | EDIT/DEL | REPLY

    제대로 공부해놔야지 해놔야지하면서 미루던건데 알기쉽게 설명해주셨네요. 감사합니다.

  • Gravatar Image.
    nguri | 2012/07/11 01:16 | PERMALINK | EDIT/DEL | REPLY

    이렇게 복잡한 포인터 선언은 유지보수를 거의 불가능하게 만들어서 후임으로 들어온 개발자를 작살낸 후에 그 유지보수는 자신만이 할 수 있음을 만천하에 알리고 끝까지 직장에서 목숨을 부지하는데 사용되는 최고 비급중에 하나입니다. 단, 자신도 꼬르륵 할 정도 바로 직전까지 정확한 수준으로 어렵게 만들어야 하는것이 포인트! 그러나 실수로 그 미세한 종이 한장 차이를 넘기는 순간 자신도 유지보수가 불가능해질수 있습니다!

  • Gravatar Image.
    Emma | 2013/01/03 15:13 | PERMALINK | EDIT/DEL | REPLY

    정말 도움 받고 갑니다^^!
    포인터가 복잡해지니까 해석에 어려움을 겪었는데
    덕분에 이해하였습니다!
    감사해요^^*

Name
Password
Homepage
Secret