※ 배열포인터의 크기는 변수로 지정할 수 있다.
#define ROWS 2
#define COLS 3
char arr[ROWS][COLS]; // 원본
int len = COLS;
char (*ptr)[len];
ptr = arr;
배열의 크기는 포인터가 가리키는 자료형의 크기가 어느정도인지 알기위한 데이터이기 때문에
미리 선언하여 공간을 잡아야하는 일반 배열과는 다르게 선언 시 동적으로 크기 지정이 가능하다.
* 함수의 매개변수로 다중배열을 받을 때
int func(void *in, int row, int col) // 크기도 함께 보내준다.
{
int ii, jj;
int (*arr)[col] = in; // 자료형지정이 안되므로 void*로 캐스팅
for(ii=0; ii<row; ii++)
for(jj=0; jj<col; jj++)
printf("arr[%d][%d] : %d \n", ii, jj, arr[ii][jj]);
return 0;
}
* 이중배열 매개변수 넘길 시 흔히 하는 실수
- 보통 아래와 같이 이중배열 자체를 매개변수로 삼아 최종 포인터를 넘기면 된다고 생각이 들지만
int func(char **in)
{
int ii;
for(ii=0; ii<NUM; ii++)
printf("Str Arr[%d] : %s \n", ii, in[ii]);
}
int main(void)
{
int ii;
char strArr[NUM][LEN] = {0,};
func(strArr);
return 0;
}
strArr나, strArr[0]나 둘다 strArr[0][0]의 주소값을 가리키고 있다.
(strArr가 strArr[0]의 주소값을 가리키지 않는다!)
배열의 메모리는 차수에 관계없이 아래 그림과 같이 1자형식으로 나열되어있다.
arr[0][0]의 주소값은 존재 하지만, arr[0][0]의 주소값을 따로 저장하지 않는다.
즉 arr[0]은 &arr[0][0]의 또다른 표현일 뿐, arr[0]라는 공간이 따로 확보된 것이 아니다.
결국 arr[0]이란 변수는 없기 때문에 &arr[0]의 값은 존재하지 않으며,
arr = &arr[0] 또한 성립하지 않는다.
그저 차수가 높아질 수록 arr[0]...[0]의 주소 표현 수단이 늘어날 뿐.(ex / arr == arr[0] == &arr[0][0])
결론적으로 배열은 저장되는 메모리의 구조적 특징으로 인해, 차수가 아무리 높아져도 해당 변수명의 포인터 차수도 증가하진 않는다.