c언어 배열 포인터 : 배열을 가리킨다.

코딩/C 2021. 3. 17. 00:58

 c언어를 공부하시다 보면, 한 번 쯤 막히는 부분이 있습니다. 배열 포인터. 쉽게 말해서 배열을 가리키는 무언가입니다. 나중에 행 우선 열 우선 방식을 할 때 다시 언급을 하고, 여기에서는 간단하게 언급을 하겠습니다. 이 글을 읽기 위해서 중요한 것은 배열은 배열 그 자체로 다루어야 한다는 점입니다.

 


 4번째 줄을 보시면, 4 by 4짜리 배열이 선언되어 있습니다. 그리고 5번째 줄에, int (*p)[4] = &(a[0])이라 되어 있는데요. 좌항부터 해석해 보겠습니다. 시계 방향 rule에 따라서 보도록 하겠습니다.

 

 

 먼저, 4번째 줄부터 해석되는데요. (*p)는 p가 포인터이다. 라는 의미입니다. 그런데, 어떤 포인터일까요? 돌려 보니까 [4]라고 되어 있습니다. 이것은 [4]개짜리의 원소를 가진다는 겁니다. 뭐가 [4]개짜리를 가질까요?

 

 

 int겠죠? 즉, int (*p)[4]는 int 자료형이 4개 저장된 배열을 가리키는 포인터를 의미합니다. 이것이 a[0]의 주소를 들고 있는 상황입니다. 이를 그림으로 도식화 시키면 아래와 같습니다.

 

 

 중요한 것은 p가 파란색으로 칠한 블록을 가리키고 있다는 것입니다. 덩어리 채로요. p[0][1]을 출력하라고 했는데요. 이것도 차례대로 봅시다. p가 int 4개를 담는 배열의 포인터라 했는데요. p는 군청색 배열을 가리킵니다. p[0]은 실 데이터이므로, 군청색 배열 그 자체입니다. p[0][1]은 그것의 [1]번째 원소이므로, 2를 출력하게 됩니다.

 

 

 예상대로 2가 나오는 군요.

 


 그러면 이 코드는 어떨까요? 중간에 p = p + 1이 나왔는데요. p가 int형 4개를 저장하는 배열 포인터였기 때문에, 4개만큼 껑충 뛰어버립니다.

 

 

 그러므로, p는 군청색 배열을 가리키게 됩니다. p[0]은 군청색 그 자체입니다. 이것의 1번째 원소이므로 6이 출력됩니다.

 

 

 6이 출력되는 모습 잘 보았습니다.

 


 여기서 부터는 배열 포인터와는 관련이 없고, 시험 문제에만 나오는 것이긴 합니다. 다만, 어렵게 나오면 어떤 식으로 플로우를 그려야 할 지만 보도록 하겠습니다. 사실 이런 문제들이 그렇게 좋지는 않다 생각합니다. 아래 예제를 보겠습니다.

 

 

 어려워 보이는데요. 사실 (*p+2)가 무엇인지만 알면 될 듯 합니다. 먼저 p가 의미하는 것은 a[0]의 주솟값이였습니다. 그러면 *p가 의미하는 것은 간단합니다. 단지, a[0] 그 자체를 의미합니다. 그런데 a[0]은 배열입니다. 이를 배열 T로 치환해서 어떻게 할 수 있다. 정도는 생각할 수 있습니다.

 

 

 그러면, *p가 군청색 그 자체이니, *p+2가 무엇인지도 볼 수 있겠군요. T[4]가 {11, 22, 33, 44}라면 T + 2는 무엇일까요? T는 배열의 시작을 가리키고, T + 2는 그로부터 2만큼 떨어진 곳을 가리킵니다. 그러면, *p+2는 33을 가리킵니다.

 

 

 여기에 [1]이 붙었습니다. *p+2의 정체는 int형을 가리키는 건데, [1]이 붙으면, 1칸 움직입니다. 그리고 []가 붙었다면, 역참조가 되어서, 실제 가리키는 값을 얻어오게 됩니다.

 

 

 44가 나오겠군요.

 

 

 재미있게도, 1차원 배열에서도 이런 것을 해 볼 수 있다는 것입니다. 그리고 이것은 제가 ps를 할 때 많이 쓰는 트릭이기도 합니다.

 

 

 5번째 줄을 보면, (a+2)[-2]라고 되어 있습니다. a+2는 3을 가리킵니다. a 배열의 2번째 위치입니다. 그리고 [-2]는 a+2를 기준으로 -2만큼 이동하는 것을 의미하는데요. a+2가 long long을 가리키므로, 2만큼 후퇴하게 됩니다.

 

 

 그 결과는 1이 됩니다. 음수 인덱스를 쓸 때 많이 쓰는 트릭이기도 합니다. 그런데, 사실 저는 저런 식으로 쓰지 않습니다. 가독성을 위해서, int *p = &(a[10]) 이렇게 해 놓고, p[-3] 이런식으로 쓰는 것을 선호합니다. 배열과 포인터는 항상 헷갈리는데요. decay of array나, 이 질답글이 문서를 천천히 보시면 감이 오실 듯 싶습니다.