[TIL]20210928
C
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");
}
}
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];
2차원 배열의 요소를 참조하는 원리.
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번이 거의 흡사하다.
서로의 차이점은 전자들의 경우 배열 또는 부분배열이고 후자의 경우 단순한 주소이다.
배열은 주소역할뿐 아니라 논리적으로 변수의 기능도 하기에 "같다"고 할수는 없다.
Author And Source
이 문제에 관하여([TIL]20210928), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kid_chang/TIL20210928저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)