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

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

작성한 질문수

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

10.13 포인터의 배열과 2차원 배열

14분 41초경 질문

해결된 질문

작성

·

211

·

수정됨

2

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

printf("%p\n", &parr[0]);
printf("%p\n", parr[0]);
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%p\n", arr[0]);
printf("%p\n", &arr[0][0]);

이 예제를 제가 설명해보면

&parr[0]은 parr[0]이라는 포인터의 주소이다.

parr[0]arr[0][0]을 가리키는 포인터이다.

arrarr[0]을 가리킨다.

&arr[0]에서 배열의 이름은 주소이기 때문에 &를 붙이던 안 붙이던 똑같다. 따라서 arr[0]과 같다.

arr[0]arr[0][0]을 가리킨다. 따라서 &arr[0]arr[0][0]을 가리킨다.

그래서 출력을 하면 arr&parr[0]을 제외한 나머지는 전부 &parr[0][0]을 출력해야 하는 것 같은데

실행 결과를 보면 arr&arr[0][0]을 출력하고 있어요.

제가 잘못 이해한 게 맞을텐데 뭐가 잘못된 건지 모르겠어요 도와주세요

질문이 너무 많아서 죄송합니다 제가 질문 게시판을 어지럽히는 것 같네요 ㄷㄷ

답변 2

3

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

 

질문이 많은 것은 괜찮습니다. 도움이 필요하실 때 마다 질문하시면 됩니다.


대부분 정확하게 이해하고 계십니다.
다만, "arrarr[0]을 가리킨다." 에서,
arr[0] 의 주소, 즉, 첫 번째 행의 시작 주소를 가리킨다고 표현하는 것이 정확합니다.

이를 마지막 부분의 "arr[0]arr[0][0]을 가리킨다. 따라서 &arr[0]arr[0][0]을 가리킨다." 를 이어보시면,
arr 또한 같은 주소를 가리킨다는 결론을 낼 수 있습니다.
생각의 흐름은 옳으시므로, 언급 드린 부분만 점검해보시면 좋을 것 같습니다.


arrint arr[2][3] 형태의 2차원 배열을 나타냅니다.
이 배열은 사실상 int[3] 형태의 배열 두 개를 포함하고 있습니다.
배열의 이름인 arr 은 배열의 첫 번째 원소인 arr[0] 을 가리키는 포인터로 사용될 수 있으며,
이는 int(*)[3] 형태의 포인터와 호환됩니다.
즉, arrint[3] 형태의 첫 번째 행을 가리킵니다.

이 때, arr&arr[0] 은 동일한 주소 값을 가집니다.

  • arrarr[0] 을 가리키며, 이는 배열의 첫 번째 행의 시작 주소입니다.

  • &arr[0] 은 배열의 첫 번째 행의 주소를 나타냅니다.

따라서, 둘 다 배열의 첫 번째 행의 시작 주소를 가리킵니다.
image

제가 지금까지 배운 여러가지 포인터 개념들이 혼동 돼서 그런지 답변해주신 게 이해가 잘 안 가는데, 포인터 개념에 대한 이전 강의들을 다시 보고와서 질문을 또 드려도 괜찮을까요? ㅜㅜ

네, 궁금하신 점이 있을 때 편하게 질문주세요.

arr[0] 의 주소, 즉, 첫 번째 행의 시작 주소를 가리킨다고 말씀을 하셨는데
arr[0]이 주소를 가질 수가 있나요? arr[0]은 배열의 이름이라 배열의 첫 번째 공간의 주소를 가리키는 것,
그러니까 arr[0][0]을 가리키는 것 뿐이지 주소를 가질 수는 없지 않나요?

 

첫 번째 행의 시작 주소를 가리킨다라고 말씀을 하신 것도 해석이 잘 안되네요
첫 번째 행의 첫 번째 공간의 주소를 가리킨다고,
그러니까 arr[0][0]을 가리킨다고 해석을 해도 괜찮을까요?

 

그리고
이 때, arr&arr[0] 은 동일한 주소 값을 가집니다. 라고 말씀을 하셨는데
arr의 메모리 공간에 있는 데이터값과 &arr[0]이라는 주소값이 같다. 라고 해석을 해도 될까요?

 

이 궁금증들이 해결이 되면 다시 공부를 이어나갈 수 있을 것 같아요.
답변 정말 감사드립니다. 그리고 같은 문제로 자꾸 질문을 해드려서 정말 죄송합니다 ㅠㅠ

https://www.inflearn.com/questions/153561

위 질문의 답변을 보고 제가 헷갈리는 부분을 찾은 것 같습니다.

배열의 이름은 포인터와 비슷한 무언가이지 포인터가 아니라 자체적인 주소가 없어 배열 이름의 주소와 배열의 이름 값이 같다는 걸 보고 헷갈리던 게 해결이 된 것 같아요. arr이라는 배열이 있을 때 arr과 &arr이 같다는 걸 보고요.

제 나름대로 생각하면서 arr = &arr[0], &arr[0] == arr[0], arr[0] = &arr[0][0] 라는 결론을 내리고 선생님이 그게 맞다고 하셨음에도 불구하고 뭔가 이해하는 방법이 틀린 것 같다고 생각이 들었는데 그 뭔가라는 제가 헷갈리는 부분이 해결된 것 같습니다.

정말 감사합니다 선생님 선생님이 답변해주시지 않았다면 여기까지 올 수도 없었을 거에요 정말 감사합니다

앞으로도 잘 부탁 드립니다

2

arr&arr[0]이다.

&arr[0]arr[0]이다.

arr[0]&arr[0][0]이다.

따라서 &arr[0]&arr[0][0]이기 때문에 arr&arr[0][0]이다.

이렇게 나름 해석을 해봤는데 제가 해석하면서도 이건 뭔가 이해하는 방법이 잘못된 거 같다는 느낌이 드네요...

  • arr&arr[0] 이다.
    : arr 은 배열의 첫 번째 원소인 arr[0] 을 가리키는 포인터입니다.

    • arr 의 타입은 int (*)[3] 으로, 이는 int[3] 배열을 가리키는 포인터입니다.

    • &arr[0] 은 첫 번째 행(arr[0])의 주소입니다. 다만, &arr[0] 의 타입은 int* 입니다.

  • &arr[0]arr[0] 이다.
    : &arr[0] 은 첫 번째 행의 주소를 나타내며, 이 주소는 arr[0] 이 가리키는 주소와 같습니다.

  • arr[0]&arr[0][0] 이다.
    : arr[0] 은 첫 번째 행을 가리키는 포인터이며, 이는 첫 번째 행의 첫 번째 원소인 arr[0][0] 의 주소를 나타냅니다.

즉, 옳게 이해하고 계십니다.

 

다만, arr&arr[0] 은 같은 메모리 주소를 가리키지만, 타입이 다르다는 점만 인지하시면 좋을 것 같습니다.
arrint(*)[3] 타입이고, &arr[0]int* 타입입니다.
포인터 타입의 차이는 포인터 연산에서 중요하므로 (질문자님의 이전 질문에서 parr 포인터에 대한 포인터 연산을 할 때의 경우와 같이), "arr&arr[0][0] 이다." 라는 표현은 메모리 주소 측면에서는 맞지만, 타입과 포인터 연산의 관점에서는 정확하지 않다는 점만 인지하시면 좋을 것 같습니다.

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

작성한 질문수

질문하기