인프런 커뮤니티 질문&답변

쉽지않네님의 프로필 이미지
쉽지않네

작성한 질문수

홍정모의 따라하며 배우는 C언어

10.14 2차원 배열과 포인터

10.14강 11:11 질문이 있습니다.

해결된 질문

작성

·

287

2

int(*ptr_arr)[3];

위 형태가 int [3] 의 배열을 가리키는 포인터라는 것은 이해했습니다.

 

int arr[3] = { 1, 2, 3 };

int* ptr_arr_1 = arr;
printf("%d\n", ptr_arr_1[1]);     // 1)

int (*ptr_arr_2)[3] = arr;
printf("%d\n", ptr_arr_2[0]);     // 2)
printf("%d\n", ptr_arr_2[0][1]);  // 3)
printf("%d\n", (*ptr_arr_2)[1]);  // 4)

1)의 경우 지금까지 써왔기 때문에 왜 arr의 1번째 요소가 나오는지 이해했습니다.

2)의 경우 printf 함수 인수가 int [3]이라는 경고가 나오고

3), 4)의 경우 arr의 1번째 요소가 출력되는 것을 확인했습니다.

 

int* ptr_arr_1 = arr;1번의 배열 역참조 연산으로 배열 요소의 값에 접근할 수 있지만

int (*ptr_arr_2)[3] = arr;2번의 배열 역참조 연산으로 배열 요소의 값이 접근할 수 있는 것 같은데

 

가리키는 배열이 똑같은 1차원 배열인데도 왜 이런 차이가 발생하는 걸까요..??

답변 1

4

안녕하세요, 답변 도우미 Soobak 입니다.

 

'포인터가 가리키는 자료형'과 '배열, 포인터 간의 관계' 때문입니다.
int* 자료형은 단일 정수를 가리키는 반면, int(*)[3] 자료형은 3 개의 정수를 가진 배열을 가리키는 자료형입니다.
포인터 연산, 배열에 대한 인덱싱 접근은 모두 포인터가 가리키는 자료형에 대한 정보를 바탕으로 수행되기 때문에, 포인터의 자료형에 따라서 접근 방식이 달라지게 되는 것입니다.

 

포인터의 연산과 배열 인덱싱은 포인터가 가리키는 자료형의 크기에 따라 다르게 수행됩니다.
int* 가 가리키는 대상은 하나의 int 이므로, 포인터 연산(예: ptr++)은 다음 int 를 가리키게 됩니다.
반면, int (*)[3]3 개의 정수를 포함하는 배열 전체를 가리키므로, 해당 포인터의 연산은 다음 배열로 이동하게 됩니다.
(예: int arr[2][3] 와 같은 2차원 배열이 있다고 가정했을 때, 이 배열에서 arr 또는 &arr[0]int (*)[3] 자료형의 포인터가 됩니다. 이 포인터가 가리키는 배열의 각 원소는 int 자료형이며, 배열 자체는 3 개의 int 를 가집니다. 따라서, int (*)[3] 포인터의 증감 연산은 해당 3int 원소를 포함하는 전체 배열을 넘어가 다음 배열로 이동하게 됩니다.)

 

따라서, int*int (*)[3] 포인터는 동일한 배열을 가리킬 수 있지만, 메모리에서 수행하는 연산과 접근 방식은 서로 다릅니다.

포인터의 유형은 포인터 연산이나 배열 인덱싱 접근 시 '메모리에서 이동하는 크기' 를 결정하게 되므로, 포인터의 유형에 따라서 가리키는 대상의 크기와 포인터 연산의 결과가 달라진다는 점을 이해하시면 도움이 되실 것 같습니다.

 

쉽지않네님의 프로필 이미지
쉽지않네
질문자

답변해주신 내용을 참고해서 2차원 배열의 포인터 관계 다시 정리했습니다..

항상 상세한 답변 감사드립니다!!

쉽지않네님의 프로필 이미지
쉽지않네

작성한 질문수

질문하기