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

김복두님의 프로필 이미지
김복두

작성한 질문수

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

11.3 문자열의 배열

3:55 질문드립니다

해결된 질문

작성

·

338

0

교수님께서 3:55쯤에 '이 주소가 아니라 이 주소에요' 라고 말씀하시는데 화면을 보면 배열 이름인 mystrings은 주소가 없어야하는게 맞다고 생각했는데 0x012ffcd0이라는 주소를 가지고있어서 의문이 생겼습니다.

배열의 이름은 포인터 상수라고 들었는데 포인터 상수이기 때문에 주소를 가질 수 없지 않나요? 아니면 포인터 상수가 아닌건가요?

배열이름은 첫번째요소를 가리키므로 첫번째요소의 주소값을 가지고 있으면 모르겠는데 mystrings의 주소와 mystrings[0]의 주소가 서로 다르네요. 0x012ffcd0 라는 주소는 어떤 의미를 가지고 있는건지 궁금합니다.

질문을 정리해보자면

1. 교수님께서 말씀해주시진 않았지만 배열의 이름은 포인터 상수라고 어느 책에서 봤는데 배열의 이름을 포인터 상수라고 정의해도 되나요?

2. 1.의 질문이 맞다면,  배열 이름인 mystrings는 포인터 상수(L-value)이므로 주소가 없지 않나요?

3.0x012ffcd0은 어떤 주소를 나타내는건지 궁금합니다.

감사합니다.

답변 3

1

1. 배열의 이름 값은 바꿀 수가 없으니 그런 의미에서 그 책에서 배열 이름을 포인터 상수라고 언급한 것 같네요. 

2, 3.

const char * 배열은 원소의 타입이 const char * 입니다. 즉, 원소 값 자체가 포인터에요! 포인터들이 모인 배열입니다. 

그러니까 지금 질문자님께서 mythings[0] 원소값을 &mythings[0] 즉 mythings[0] 의 주소라고 오해하신거에요!!! 3:55 에서 [0] 부분은 mythings[0] 원소값이지 &mythings[0] 를 뜻하는게 아닙니다.

mythings 배열은 원소의 타입이 포인터이기 때문에 원소값 자체가 주소값입니다.  mythings[0] 는 주소값, &mythings[0] 는 포인터의 주소값! 이 되겠네요.

그러니 해당 3:55 에서 보여지는 0x00787b30 은 &mythings[0] 이 아니라!!!!! mythings[0] 원소값인거에요!!! 

질문 주신 0x012ffcd0 는 &mythings[0] (배열 이름과 같은 첫번째 원소의 주소값) 이 맞구요!!! 

아무래도 원소 또한 포인터이기 때문에 오해하신 것 같습니다. ㅎㅎ 

요약하자면 배열 이름 그 자체는 주소 없는게 맞구요! mythings[0] 값인 0x00787b30  을 &mythings[0] 로 오해하신 것입니다. mythings[0] 를 &mythings[0] 로 오해하시어 이게 배열 이름 값과 동일하지 않으니 배열이름 그 자체도 주소가 있는 것인가 하고 혼란이 생기셔서 질문 주신 것 같습니다. mythings 값인 0x012ffcd0 는 그 배열 이름의 주소가 아닌 &mythings[0] 값인게 맞습니다. 

 (그리고 여담으로 L-value 보단 R-value 가 적합해보입니다. L-value 는 주소 있는거에요!)

0

배열명(identifier)은 lvalue입니다.

그리고 "배열이름이 포인터 상수다"라고 하는 것보다 배열이름이 포인터로 "형변환"된다라고 하는 게 맞다고 생각합니다.

왜냐하면 특정 경우를 제외하고, 배열 타입의 표현식(지금의 경우는 배열명)이 첫 번째 원소를 가리키는 포인터로 형변환되기 때문입니다.

아래는 제가 스택 오버플로우에서 찾은 질문과 관련된 답변과 함께 C 표준(C standard)를 참조한 내용입니다.

(제가 잘못 해석했을 수도 있기 때문에 잘못된 부분이 있으면 지적바랍니다.)

1. lvalue는 개체(object)를 나타내는(designate) 표현식이다.

2. 식별자는 개체(object)를 나타내는(designate) 것으로 선언된다면, 주 표현식(primary expression)이다. (이 경우에 식별자는 lvalue이다.)

3. sizeof 연산자와 & 연산자의 피연산자, 배열 초기화에 사용되는 문자열 리터럴일 때를 제외하고,

"어떤 형(type)의 원소로 이루어진 배열"을 나타내는 표현식은 배열 개체의 첫 번째 원소를 가리키는 "어떤 형(type)에 대한 포인터"를 나타내는 표현식으로 형변환되며 lvalue가 아니다.

스택 오버플로우

여기서, 앞의 표현식은 배열명(식별자)이고 뒤의 표현식은 &배열명[0]를 의미하는 것 같습니다.

&는 주소값을 계산하므로 rvalue(표현식값)가 됩니다.

배열은 배열이고 포인터는 포인터이기 때문에, '배열이름이 포인터 상수다'는 적절하지 않습니다.

새롭게 배워가네요... 많이 알아갑니다. 정말 감사드립니다! 

0

김복두님의 프로필 이미지
김복두
질문자

헷갈렸었는데 덕분에 정리가 되었습니다. 오개념 또한 바로잡아주셔서 감사드려요!

김복두님의 프로필 이미지
김복두

작성한 질문수

질문하기