다차원 배열과 포인터의 관계

유석현(SeokHyun Yu)·2022년 7월 20일

C

목록 보기
18/26
post-thumbnail

1. 2차원 배열이름의 포인터 형

int arr[3][3];

다음과 같이 선언된 2차원 배열이 있다고 가정해보자.

2차원 배열의 경우 arr[0], arr[1], arr[2]도 의미를 갖는다.

이들은 각각 1행, 2행, 3행의 첫 번째 요소를 가리킨다.


int arr[3][3];

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

위 문장의 출력 결과는 모두 같다.

또한 배열 이름 arr을 대상으로 sizeof 연산을 하는 경우 배열 전체의 크기를 반환하고, arr[0], arr[1], arr[2]를 대상으로 sizeof 연산을 하는 경우 각 행의 크기를 반환한다.

결론적으로 arr은 첫 번째 요소를 가리키면서 배열 전체를 의미한다.

하지만, arr[0]은 첫 번째 요소를 가리키되 1행만을 의미한다., arr과 arr[0]은 서로 다른 것이다.

int arr[3][3];

printf("%p", arr+1);

2차원 배열 이름을 대상으로 증가 및 감소연산을 할 경우, 연산결과는 각 행의 첫 번째 요소의 주소 값이 된다.

따라서 위 소스코드에서 arr+1은 arr[1]과 동일한 의미이다.


따라서 2차원 배열을 포인터 변수로 받으려면 다음과 같이 하면 된다.

int (*ptr)[4];
char (*arr1)[5];
double (*arr2)[6];

위 코드를 조금 보충하면 변수 ptr앞의 * 선언은 ptr이 포인터 선언이 되게 한다.

그리고 [4]는 포인터 연산 시 4칸씩 건너뛰되, ptr이 가리키는 변수가 int형 변수이기 때문에 int형 변수를 4칸씩 건너뛴다는 의미가 되는 것이다.

그리고 위와 같은 포인터 변수는 2차원 배열을 가리키는 용도로만 사용되기 때문에 이러한 유형의 포인터 변수를 가리켜 '배열 포인터 변수'라 한다.

그리고 각각의 특징은 다음과 같다.

arr1은 char형 변수를 가리키면서,

포인터 증감 연산 시 sizeof(char)*5의 크기단위로 값이 증가 및 감소하는 포인터 변수
arr2은 double형 변수를 가리키면서,

포인터 증감 연산 시 sizeof(double)*6의 크기단위로 값이 증가 및 감소하는 포인터 변수

int arr1[2][2]={ {1, 2}, {3, 4} };
int arr2[3][2]={ {1, 2}, {3, 4}, {5, 6} };
int arr3[4][2]={ {1, 2}, {3, 4}, {5, 6}, {7, 8} };

int (*ptr)[2];

ptr=arr1;
ptr=arr2;
ptr=arr3;

arr1, arr2, arr3 모두 int형 2차원 배열이면서 가로의 길이가 동일하니, 이들 배열이름의 포인터 형은 모두 동일하므로 ptr에 대입연산이 모두 가능하다.


2. 2차원 배열이름의 특성과 주의사항

'포인터 배열''배열 포인터'를 혼동하면 안 된다.

int num1=10, num2=20;
int arr[2][2]={1,2,3,4};

int * ptr1[2]={&num1, &num2}; // 포인터 배열
int (*ptr2)[2]=arr; // 배열 포인터

void Func(int (*ptr1)[7], double (*ptr2)[5])
{
   ...
}
void Func(int ptr1[][7], double ptr2[][5])
{
   ...
}

두 매개변수 선언은 동일하다.


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

printf("%d", arr[2][1]);
printf("%d", (*(arr+2))[1]);
printf("%d", *(arr[2]+1));
printf("%d", *(*(arr+2)+1));

위 출력은 모두 같다.

profile
Backend Engineer

0개의 댓글