강의

멘토링

로드맵

Inflearn brand logo image

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

조범상님의 프로필 이미지
조범상

작성한 질문수

독하게 시작하는 C 프로그래밍

2차원 배열 포인터 질문

해결된 질문

작성

·

94

·

수정됨

0

int a[2][3] = { {1, 2, 3}, {4, 5, 6} }; int sum = (a+0) + (a+1) + (a+2);
여기서 내가 모르겠는 부분은 a는 배열이기 때문에 a[0]이 a의 주소로 참조 되고 주소를 100이라고 가정한다면 a는 100의 값이 저장된다. 이때 *a는 왜 1이 아니고 *a는 100번지라는 주소를 가지는 건가요??

 

1차원 배열 포인터는 주소의 위치 값을 말한다고 배웠는데 배열에서는 적용이 다른 거 같아서 헷갈리는데 2차원 배열의 특징으로 외워야 하는 건가요?

GPT 설명
🔎 핵심: a, *a, a[0], &a[0][0] 모두 주소는 같아도 타입이 다르다

표현의미타입주소값 예시a2차원 배열의 첫 번째 행의 주소int (*)[3]100*a첫 번째 행 a[0]int[3]100a[0]첫 번째 행int[3]100&a[0][0]첫 번째 요소의 주소 (즉, 1의 주소)int*100**aa[0][0] == 1int(값) 1
*a == a[0] == 주소, **a == a[0][0] == 값
저는 a = 100 인데 *a도 100인게 이해가 안되요

답변 3

0

널널한 개발자님의 프로필 이미지
널널한 개발자
지식공유자

2차원 배열은 1차원 배열을 요소로 갖는 1차원 배열입니다.

int a[2][3] 배열은 int[3] 배열을 요소로 갖고 있는 배열입니다. 그리고 a는 int[2][3] 형식의 2차원 배열이며 식별자가 a인 2차원 배열입니다. 그러므로 a + 1 연산에서 1은 그냥 1바이트가 아니라 int[3] 크기 입니다.

a[0]이 a와 같은 이유는 모든 배열의 0번 요소의 주솟값은 배열의 이름과 같기 때문입니다. 그리고 *a 연산의 결과는 int[3] 배열을 가리킬 수 있는 주소(상수)입니다. l-value가 아니라 상수가 되는 것이죠. 배열의 이름은 주소 상수입니다.

a도 주소상수, *a는 1회 간접지정한 것이고 a가 2차원 배열이니 아직도 주소 입니다. 결과적으로 모두 같은 주소가 됩니다. 참고 하시기 바랍니다. 😄

 

0

조범상님의 프로필 이미지
조범상
질문자

또 포인터 배열의 경우
int arr[3][3] = {

{1, 2, 3}, // arr[0]

{4, 5, 6}, // arr[1]

{7, 8, 9} // arr[2]

};

int darr[2] = {arr[1], arr[2]}; 일 때,
darr의 개념도 헷갈립니다. darr는 arr[1]을 말하고 arr[1]은 103번(1바이트씩 떨어져 있다고 가정했을 때 )인데 103이런 구조인데 이것이 아니고, 사실 위처럼 darr는 arr[1]이고 *darr이 arr[1][0]이라는 결과인데 , 여기도 darr = arr[1] = *darr[1] 이런 구조가 이해가 안되요

0

안녕하세요, 인프런 AI 인턴입니다.
조범상님께서 문의하신 내용은 2차원 배열과 관련된 포인터 연산에 관한 것으로 보입니다. 이 주제는 C 언어의 배열과 포인터 이해에 있어 중요한 부분입니다. 이어서 이를 이해하는 데 도움이 되는 설명을 드리겠습니다.

2차원 배열에서 각 요소가 메모리에 어떻게 저장되고 포인터가 어떻게 작동하는지에 대한 고민이시라면, 아래 설명이 도움이 될 것입니다.

2차원 배열과 포인터 이해

  1. 배열 및 포인터 기초:

    • int a[2][3]는 2개의 행과 3개의 열로 구성된 배열입니다.
    • a는 배열의 시작 주소를 가리키며, int (*)[3] 타입의 포인터로 해석됩니다.
  2. 주소 접근과 값 출력:

    • *a는 첫 번째 행의 시작 주소를 가리키지만, 값으로 해석할 때 a[0]과 동일한 의미를 가집니다.
    • a[i]는 i번째 행 전체를 가리킵니다. 즉, a[0]{1, 2, 3}을 가리키고, a[1]{4, 5, 6}을 가리킵니다.
    • &a[0][0]은 배열의 첫 번째 요소인 1의 주소를 나타냅니다.
  3. 데이터 타입의 차이:

    • a, *a, a[0], &a[0][0]은 주소는 같을 수 있지만, 그 타입이 다릅니다. 이는 메모리 접근 시 어떤 크기와 형태로 해석되는지를 결정합니다. 예를 들어, a는 크기가 3인 정수 배열에 대한 포인터로 해석됩니다.
  4. 값 접근:

    • **aa[0][0]과 동일하며, 배열의 첫 번째 요소의 값을 나타내는, 즉 여기에선 1이 됩니다.
    • 따라서 *(*a + n)은 n번째 요소의 값을 가져오는데 사용되며, 예를 들어 *(*a + 1)a[0][1]이 됩니다.

이해의 핵심은 2차원 배열을 배열의 배열로 보고 각 배열의 시작 주소와 타입이 어떻게 지정되어 있는지를 이해하는 것입니다. 배열과 포인터의 타입과 주소, 값을 혼동하지 않는 것이 중요합니다.

이 주제와 유사한 질문이 추가로 있으신 경우 C 언어의 다차원 배열과 포인터에 대한 질문을 확인하실 수 있습니다. 질문 전반을 이해하실 수 있도록 해당 답변을 참고하세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

조범상님의 프로필 이미지
조범상
질문자

"*a는 첫 번째 행의 시작 주소를 가리키지만, 값으로 해석할 때 a[0]과 동일한 의미를 가집니다." 이 부분을 2차원배열의 특징으로 암기해야 하는 건가요??

조범상님의 프로필 이미지
조범상
질문자

또 포인터 배열의 경우
int arr[3][3] = {

{1, 2, 3}, // arr[0]

{4, 5, 6}, // arr[1]

{7, 8, 9} // arr[2]

};

int darr[2] = {arr[1], arr[2]}; 일 때,
darr의 개념도 헷갈립니다. darr는 arr[1]을 말하고 arr[1]은 103번(1바이트씩 떨어져 있다고 가정했을 때 )인데 103이런 구조인데 이것이 아니고, 사실 위처럼 *darr는 arr[1]이고 **darr이 arr[1][0]이라는 결과인데 , 여기도 darr = arr[1] = *darr[1] 이런 구조가 이해가 안되요

조범상님의 프로필 이미지
조범상

작성한 질문수

질문하기