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

CJS님의 프로필 이미지
CJS

작성한 질문수

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

10.14 2차원 배열과 포인터

int (*pa)[4]와 int*pa의 차이

작성

·

457

·

수정됨

1

#include <stdio.h>

int main()
{
	float arr2d[2][4] = { {1.0f,2.0f,3.0f,4.0f},{5.0f,6.0f,7.0f,8.0f} };

	float(*pa)[4] = arr2d;

	printf("%u %u \n", (unsigned)pa, (unsigned)(pa + 1));
	printf("%u %u\n", (unsigned)arr2d[0], (unsigned)arr2d[1]);
	printf("%u %u\n", (unsigned)pa[0], (unsigned)(pa[0] + 1));
	printf("%f\n", pa[0][0]);
	printf("%f\n", *pa[0]);
	printf("%f\n", **pa);
	printf("%f\n", pa[1][3]);
	printf("%f\n", *(*(pa + 1) + 3));

	float* ptr = arr2d;

	printf("%u %u \n", (unsigned)ptr, (unsigned)(ptr + 1));
	printf("%u %u\n", (unsigned)arr2d[0], (unsigned)arr2d[1]);
	printf("%u %u\n", (unsigned)ptr[0], (unsigned)(ptr[0] + 1));
	printf("%f\n", ptr[0][0]);
	printf("%f\n", *ptr[0]);
	printf("%f\n", **ptr);
	printf("%f\n", ptr[1][3]);
	printf("%f\n", *(*(ptr + 1) + 3));


}

강의 9:47에서 int(*pa)[4]가 나옵니다.

강의 10:20에서 교수님께서 pa는 4개의 float자료형을 가진 배열에 대한 포인터라고 하셨습니다.

저는 이것을 [4개의 float자료형을 가진 배열]의 배열에 대한 즉, 2차원배열에 대한 포인터라고 이해했습니다.

float arr[4] = { 1.0f,2.0f,3.0f, 4.0f };
float(*pa)[4] = arr;

Q1. 위처럼 (*pa)[4]에 1차원 배열도 넣을수 있는건가요? float(*pa)[4]에서 [4]가 헷갈리는것같습니다. 정확히 정의를 내리기가 힘듭니다. float(*pa)[4]란 무엇인가요?

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

pa는 어쨋든 그냥 단순한 포인터 변수 하나 라고 이해했습니다.

그래서 똑같이

float* ptr = arr2d; 포인터 변수를 하나 선언하고 거기에 2차원 배열([4개의 float자료형을 가진 배열]의 배열을 넣어줬습니다.

저는 pa ptr은 그냥 외형만 다를뿐 문법적으로 같은 포인터변수라고 이해했습니다.

그런데 pa같은 경우

printf("%f\n", pa[0][0]);
printf("%f\n", *pa[0]);
printf("%f\n", **pa);
printf("%f\n", pa[1][3]);
printf("%f\n", *(*(pa + 1) + 3));

이중포인터처럼 사용가능한 반면

ptr의 경우는

printf("%f\n", ptr[0][0]);
printf("%f\n", *ptr[0]);
printf("%f\n", **ptr);
printf("%f\n", ptr[1][3]);
printf("%f\n", *(*(ptr + 1) + 3));

이중포인터처럼 사용하면 밑줄이 뜨고 오류가 떳습니다.

포인터.jpg그림을 그려보니 ptr은 당연히 단순 포인터변수이기에 이중포인터처럼 사용은 불가능했습니다.

 

Q2.그렇다면 어째서 pa는 포인터변수인데도 이중포인터처럼 사용이 가능한건가요? 또 pa와 ptr의 차이는 무엇인가요?

 

항상 감사합니다. 진짜 진짜 진짜 감사합니다.

 

답변 2

2

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

질문 1 ) float(*pa)[4] 에 대하여
: float(*pa)[4]4 개의 float 원소를 가진 배열에 대한 포인터 를 의미합니다.
즉, pafloat 자료형 4 개가 들어있는 배열을 가리키는 포인터이므로, float arr[4] 와 같은 1차원 배열도 이 포인터에 할당할 수 있습니다.

질문 2 ) pa 가 이중 포인터처럼 사용이 가능한 이유, 그리고 paptr 의 차이점
: 우선 paptr 의 자료형에 대해서 설명드린 후 나머지 내용에 대해서 말씀드리겠습니다.

  • float(*pa)[4] : 4 개의 float 원소를 가진 배열에 대한 포인터입니다.

  • float* ptr : 단순히 float 에 대한 포인터입니다. 따라서, 이에 2차원 배열인 arr2d 으로 초기화를 시도하면 경고가 발생하게 됩니다. (컴파일러의 경고 수준에 따라서 다르기도 합니다.)


따라서,

  • pa 는 2차원 배열의 각 행(차원)을 가리킬 수 있습니다.
    즉, pa[0] 은 첫 번째 행(차원)을, pa[1] 은 두 번째 행(차원)을 가리키게 됩니다.
    그렇기 때문에 pa[0][0] 과 같은 표현이 가능한 것입니다.

     

pa 가 "이중 포인터 처럼" 보이는 이유는, pa 의 자료형 특성 상 2차원 배열의 행(차원)에 대한 포인터로 동작하기 때문입니다. 따라서, pa 를 사용하여 2차원 배열의 원소에 pa[행][열] 과 같이 접근할 수 있는 것입니다.

요약하면, paptr 은 같은 주소를 가리키지만, 서로 다른 자료형의 포인터이기 때문에 질문 주신 내용에 대한 의문점들이 생기신 것이라고 말씀드리는 것이 적절한 것 같습니다.

항상 좋은 질문을 해주셔서 저 또한 감사드립니다.

1

CJS님의 프로필 이미지
CJS
질문자

감사합니다. 혈이 뚫리는 답변 감사합니다.

CJS님의 프로필 이미지
CJS

작성한 질문수

질문하기