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

용개형멋져님의 프로필 이미지
용개형멋져

작성한 질문수

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

10.15 포인터의 호환성

6분 54초경 질문

해결된 질문

작성

·

281

·

수정됨

2

그냥 그렇나 보다 하고 지나칠뻔한 걸 한번 의심을 하니 문제를 놓을 수가 없게 되었습니다.

 

1.

int ar1[2][3] = { {1, 2, 3}, {4, 5, 6} };

int* pt;

pt = &ar1[0][0];

for (int i = 0; i < 6; ++i)
printf("%d %d ", pt[i], *(pt + i));

 

2.

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

int* parr[2];

parr[0] = arr[0];
parr[1] = arr[1];

for (int i = 0; i < 2; ++i)
printf("%p %p ", parr[i], *(parr + i));

 

둘 다 똑같이 출력을 했는데 1번 예제는 값이, 2번 예제는 주소가 출력 되는 이유
그러니까 parr[i]가 주소를 출력하니 pt[i]도 주소를 출력 해야 할 것 같은데 값을 출력하는 이유가 궁금합니다.
parr은 포인터의 배열이고 pt는 포인터라서?
parr의 자료형은 int (*)[3]이고 pt의 자료형은 int*라서?
뭔가 연관이 있을 텐데 저는 어떤 연관이 있는 건지 쉽사리 연결 지을 수가 없더라구요.
꼭 알려주셨으면 합니다.

 

항상 좋은 답변 감사합니다.

 

답변 2

2

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


간단하게, ptparr 이 가리키는 대상의 타입이 다르기 때문입니다.

첫 번째 예시 코드에서 pt 는 단일 포인터 (int*) 이며, 배열의 각 원소 값에 접근합니다.
반면, 두 번째 예시 코드에서 parr 은 포인터의 배열이며, 각 포인터가 배열의 행을 가리키는 주소를 저장합니다.
따라서 pt[i] 는 값으로 해석되고, parr[i] 는 주소로 해석됩니다.

1

이것도 비슷한 질문인 것 같은데

int* pt;
int(*pa)[3];

int ar1[2][3] = { 3, };

에서

pt = &ar1[0][0];
pt = ar1[0];

이렇게 대입하는 건 가능한데

pt = ar1;

이렇게 대입하는 건 불가능한 이유는 ar1 자체는 2차원 배열이기 때문에 그냥 포인터에는 담을 수가 없다.
고 말씀을 하셨는데 그렇다면 포인터의 배열에는 담을 수가 있다는 말씀이신 거잖아요.

어째서 2차원 배열이기 때문에 그냥 포인터에는 담을 수가 없고 포인터의 배열에는 담을 수가 있다는 건가요?
2차원 배열의 행과 포인터 배열의 크기가 같아야해서? 인가요?

구글링하면서 스스로 나름의 답을 찾아보았는데 이게 맞는 생각인지는 모르겠습니다.

pt에는 열이 없지만 굳이 있다고 하면 크기는 1이고 ar1의 열의 크기는 3이라, 만약 대입을 할 경우 다음 행으로 넘어가는 포인터 산술 연산을 했을 때 다음 행이 아니라 다음 행의 다음으로 넘어갈 수도 있기 때문이다.
워낙 제 입장에서 쓴거라 이해가 가능하실지는 모르겠네요.. 죄송합니당...

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

네, 이해하신 내용과 같은 맥락입니다.
배열과 포인터의 관계는 배열의 차원과 타입에 따라서 달라집니다.
2차원배열은 int* 포인터에 직접 할당될 수 없으며, 대신 int(*)[열의 크기] 형태의 포인터를 사용해야 합니다.
포인터의 배열은 각 포인터가 배열의 한 행을 가리킬 수 있도록 구성됩니다.

용개형멋져님의 프로필 이미지
용개형멋져

작성한 질문수

질문하기