작성
·
298
0
int arr[2][3] = { { 1, 2, 3 },
{ 4, 5, 6 } };
int* parr[2] = { arr[0], arr[1] };
printf("%p\n", &parr[0]); // 1
printf("%p\n", parr[0]);
printf("%p\n", arr);
printf("%p\n", &arr[0]); // 2
printf("%p\n", arr[0]);
printf("%p\n", &arr[0][0]);
강의 내용중 , 위의 코드와 관련하여 질문 드립니다!
일단, arr[0] 이라는 이름이, 배열이름으로 사용되어 포인터처럼 동작한다고 이해했습니다.
즉, arr[0] 이라는 배열의 첫번째 원소를 가리키는 주소를 담은 포인터 인것으로요!
Q1. 위 이해가 맞는지 여쭙고 싶습니다.
그렇다는 가정 하에, &parr[0] 가 결과가 다르게 나오는 것도 이해를 할 수 있습니다.
parr[0] 은 arr[0] 이라는 포인터이고, & 연산자로 "그 포인터의 주소"를 출력하는 것이니까요 이중포인터처럼 이해했습니다.
그런데 여기서 주석 2의 출력 결과가 다르게 나오는 부분이 이해가 가지 않습니다.
arr[0] 은 배열 이름으로 사용되고, 포인터로 동작을 하는데, &arr[0]을 찍으면 그 포인터의 주소가 나와야 하는 것이 아닌지....
parr[0] = arr[0] 인데 말입니다!
Q2. parr[0] = arr[0] 인데, &parr[0] 은 포인터의 주소를 출력하고 &arr[0]은 어떤 원리로 다른 값을 출력하는지 궁금합니다
parr이라는 "포인터 배열"을 통해 접근할때는 arr[0]이 포인터처럼 자기 자신의 주소를 그제서야 갖게되고,
그냥 arr[0] 으로 직접 접근하면 그냥 배열명이기 때문에, 자기 자신의 주소는 없는 그런건가요?
답변 3
2
Q1 맞습니다! 포인터는 그냥 독립적인 공간인 어떤 변수라고 생각하시면 됩니다. 꼭 arr 배열 뿐만아니라 다른 것들도 다 가리킬 수 있죠. int a = 2 같은 이런 값을 저장하고 다른 값으로 수정할 수 있는 L-value 인 공간이니 당연히 유효한 주소를 가지고 있고 이는 ptr != &ptr 라는 것에 연결될 수 있습니다. 반면 배열 이름은 위에서도 말씀드린 것처럼 R-value처럼 생각하시면 되요. 그냥 arr이라는 특정 배열의 첫번째 원소 주소값 그 자체라.. 딱히 주소가 있진 않은..? 나머지 질문들도 Q1과 제가 링크해드린 주소로 이해하실 수 있을거라고 생각됩니다.
parr도 배열 이름이니까 parr과 &parr은 값이 같습니다. parr의 원소 타입들이 포인터일 뿐이지 parr이 배열 이름이라는 사실은 변함 없죠.
1
안녕하세요.
A1. 배열 이름의 주소를 찍어보면 원래 배열의 이름 값이랑 똑같습니다. arr = &arr 와 같아요! 포인터랑 배열의 이름이랑 조금 다르게 생각해보셔야 할게.. 포인터는 배열과 상관없는 변수입니다. 그냥 어떤 주소든 다 저장할 수 있는데 마침 ptr = arr 로 배열의 주소 값을 대입받은 것 뿐이지요. 그러니 포인터는 int a, int b 이런 것 처럼 본인만의 공간이 있습니다. "변수"이기 때문이에요! 이 공간에 대입 받은 주소를 저장하는 방식입니다. 이와 반면에 배열의 이름은 포인터처럼 따로 "변수"로서 저장되는게 아니에요.(사실 시스템상 어딘가에 저장은 되있겠지만 그걸 "변수"처럼 접근할 순 없는 것 같아요) 그래서 &arr 은 그냥 arr와 값이 같습니다. 그냥 arr은 포인터처럼 배열의 첫번쨰 원소의 주소를 저장하는 어떤 독립적인 공간이라고 생각하기보단 그냥 첫번째 원소 주소값 자체인.. 마치 R-value 처럼 생각해주시면 이해하기 수월하실 것 같아요. &arr 도 그냥 "arr자체의 주소"가 아닌, 첫번쨰 원소의 주소라고 생각해주시면 됩니다. (다만, 값은 같지만 데이터 타입은 서로 다릅니다.)
https://stackoverflow.com/questions/2528318/how-come-an-arrays-address-is-equal-to-its-value-in-c
링크 참고해주세요.
A2. 위의 설명과 링크로 답변이 될 것 같습니다. 맞아요 그냥 자기 자신의 주소는 없다고 생각하시면 될 것 같아요..! (시스템상 실제론 있긴 하겠지만 그냥 배열의 이름은 일반 포인터 변수처럼 개발자가 접근할 수 있는 공간에 값이 있는게 아닌듯 해요!)
0
답변 감사합니다! 이해를 확인하고자 조금만 더 질문 드리겠씁니다..
아직 개념에 혼란이 많아 중복되는 질문이 있을 것 같아요 ㅠㅠ
Q1. 상단 첨부의 이해가 맞는지, 잘못 이해한 부분이 있는지 확인 부탁드리고 싶습니다 ㅠㅠ
Q2. 기본적으로 arr == &arr[0]이고, 거기에 이제 &arr도 같은 것이라는 것을 알게 됐구요!
Q3. 그런데 Q2의 내용은 arr이 평범한 배열일 때고,
parr처럼 포인터의 배열이라면
&parr은 따로 주소를 갖게 되는건가요? 아니면 Q2의 정리 그대로일까요?
Q4. 강의 중 Notes 부분에서 ( 하단 첨부 사진)
& arr[0] == arr[0] 인 이유는 arr[0] 이 배열명이고, &배열명 == 배열명 == &첫원소 기 때문이고,
& parr[0] != parr[0] 인 이유는 parr[0] 값이 배열명 arr[0]과 같긴 하지만 parr[0]은 배열명이 아닌 포인터로서의 선언이 되었기 때문인건가요?
즉 포인터 선언 한 경우랑 아닌경우 차이인가요?
(써놓고 보니 Q1과 같은 맥락의 질문이긴 하네요...)