int main(){
int ary[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*pa)[4]; //4칸짜리 배열덩어리 전체를 가리키는 포인터.
int i, j;
pa=ary;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
printf("%5d",pa[i][j]);
}
printf("\n");
}
}
쌉소리 주의. 다 틀린말일 수도...
2차원 배열과 배열 포인터.
배열 포인터는 배열을 가리키는 포인터로 2차원 배열의 이름(묶음 묶음들 ->즉, 열(column))의 주소 단위로 저장한다.(주소에서 +1을 하면 묶음 내부에서 한칸 이동이 아닌 다음 열로 이동.)
{배열의 주소라고 하지않는 이유는 배열 맨앞 한 칸을 가리키는 것이 아닌 배열 한 줄 전체를 지시함을 표시하기위함임}
1차원 배열은 논리적인 배열 요소 이지만 1차원 요소를 여러개 나열한 2차원 배열은 전체로 보면 1차원 배열 맨 앞의 주소를 여러개 가지고 있는 일반적인 배열이다.
위의 코드에서 {x, x, x, x}이라는 논리적인 1차원 배열이 여러개일때 주소+1을 하면 다음번의 1차원 배열로 넘어간다.
그렇기 때문에 int (pa)[4];를 통해서 int[4](4칸짜리 int형 배열)을 담을 함수를 만든다. pa는 한 줄(열(column))씩 묶는 포인터. 이 코드는 포인터 함수를 이용한 것은 맞지만, "포인터 배열"이 아니다.! 배열 포인터이다.
arr[3][4]일때 2차원 배열의 논리적 입장에서는 arr[0], arr[1], arr[2] 세 덩이로 구분된다.
int (*pa)[4];
는 {1,2,3,4}덩어리, {5,6,7,8}덩어리, {9,10,11,12}덩어리 각각을 가리키기위해 (*pa)를 쓴 것이고 각각의 덩어리 내부는 4칸으로 구성되어있기에 [4]를 사용. (int[4]라고 생각.)
복잡해서 다시 요약하자면
4칸짜리 1차원 배열 내부는 포인터로 접근시키고 이 묶음들은 "일반적인" 배열로(arr[0], arr[1]처럼) 인식 코드이다...
https://blockdmask.tistory.com/56 누군가 잘 정리한 글을 보자
그냥. 요약.
포인터 배열: 포인터들(주소)를 배열에 담은 것. 선언예시:char* arr[3];
배열 포인터: 배열을 가리키는 포인터. 선언예시:char (*arr)[3];
arr[3][4]
배열에 1~12숫자를 차례대로 넣는다고 가정하자.
7번째 물리적 요소를 접근하는 방법
1. 7번째 물리적 요소는 두 번째 부분배열(col 덩어리)에 속함으로 시작 위치를 구해야함. (밑의 값중 100단위는 메모리 번지)
ary+1 -> 100(1sizeof(arr[0])) -> 100 + 16 -> 116
이때 sizeof(arr[0])은 ary가 가리키는 첫 번째 부분배열의 크기.
arr[1]에 접근했다면 이제 이 배열 안에서 추가적인 접근을 해줘야하는데
(arr+1)+2 하면 당연히 안된다. 저러면 arr+3이 되고 부분배열자체를 건너뛰고 다음 3번째의 부분배열에 접근하는 것이다.
*(arr+1) -> arr[1]
*(arr+1) +2 -> *(arr+1) + (2 sizeof(arr[1][0])) -> 116 + 8 -> 124
이런 방식으로 접근 해야한다. 부분배열 밖을 겉돌때는 *가 없고 부분배열 내부를 접근할땐 *가 사용된다는 것을 잘 알아두자.
124는 배열의 주소값임으로 상자안의 값을 사용하려면 *(*(arr+1)+2)
-> arr[1][2]
로 접근하면 된다.
정리
int ary[3][4];
가 있을때.
&ary
: (1) 2차원 배열 "전체"의 주소
ary
: (2) 첫 번째 부분배열의 주소 // sizeof -> 48바이트
&ary[0]
: (3) 첫 번째 부분배열의 주소 // sizeof -> 4바이트
ary[0]
: (4) 첫 번째 부분배열의 첫 번째 배열 요소의 주소 // sizeof -> 16바이트
&ary[0][0]
: (5) 첫 번째 부분배열의 첫 번째 배열 요소의 주소 // sizeof -> 4바이트
2, 3번이 거의 흡사하고 4, 5번이 거의 흡사하다.
서로의 차이점은 전자들의 경우 배열 또는 부분배열이고 후자의 경우 단순한 주소이다.
배열은 주소역할뿐 아니라 논리적으로 변수의 기능도 하기에 "같다"고 할수는 없다.