C 배열 포인터 - sonkoni/Koni-Wiki GitHub Wiki
괄호의 유무에 따라 의미가 달라진다.
== 포인터배열: 배열이다. ==
자료형 *배열이름[카운트]; // `자료형으로 된 포인터`를 카운트만큼 담을 수 있는 배열
int *numPtrArr[4]; // `int 형 포인터`를 4개 담을 수 있는 배열
== 배열포인터: 포인터이다. ==
자료형 (*포인터이름)[카운트]; // `자료형 요소를 카운트만큼 가지고 있는 배열`을 가리키는 포인터
int (*numArrPtr)[4]; // `int 요소 4개를 가지고 있는 배열`을 가리키는 포인터
#include <stdio.h>
int main(int argc, char *argv[]) {
int nArr[4] = {11, 12, 13, 14};
printf("nArr: %p, %p\n", &nArr, nArr);
printf("nArr: %p, %d\n", &nArr[0], nArr[0]);
return 0;
}
// nArr: 0x7ff7bbb525b0, 0x7ff7bbb525b0
// nArr: 0x7ff7bbb525b0, 11배열은 특이하다. 배열은 0번인덱스의 포인터주소이다. 따라서 &nArr과 nArr과 &nArr[0]은 같다.
#include <stdio.h>
int main(int argc, char *argv[]) {
int a, b, c;
a = 1, b = 2, c = 3;
int *aPtr = &a;
int *bPtr = &b;
int *cPtr = &c;
int *numPtrArr[3] = {aPtr, bPtr, cPtr};
printf("%p, %p\n", numPtrArr[0], aPtr);
printf("%p, %p\n", numPtrArr[1], bPtr);
printf("%p, %p\n", numPtrArr[2], cPtr);
printf("%d, %d\n", *numPtrArr[0], *aPtr);
printf("%d, %d\n", *numPtrArr[1], *bPtr);
printf("%d, %d\n", *numPtrArr[2], *cPtr);
return 0;
}
// 0x7ff7beb6d59c, 0x7ff7beb6d59c
// 0x7ff7beb6d598, 0x7ff7beb6d598
// 0x7ff7beb6d594, 0x7ff7beb6d594
// 1, 1
// 2, 2
// 3, 3포인터배열은 포인터를 담고 있는 배열이다. numPtrArr[0]은 aPtr과 같다.
#include <stdio.h>
int main(int argc, char *argv[]) {
// int numArr[3][4] = {
// {11, 12, 13, 14},
// {21, 22, 23, 24},
// {31, 31, 33, 34}
// };
int n0Arr[4] = {11, 12, 13, 14};
int n1Arr[4] = {21, 22, 23, 24};
int n2Arr[4] = {31, 31, 33, 34};
int *nPtrArr[3] = {n0Arr, n1Arr, n2Arr};
printf("%p, %p\n", nPtrArr[0], n0Arr);
printf("%zu, %zu\n", sizeof(nPtrArr[0]), sizeof(n0Arr));
printf("%d, %d\n", nPtrArr[0][1], n0Arr[1]);
return 0;
}
// 0x7ff7b243d5b0, 0x7ff7b243d5b0
// 8, 16
// 12, 12포인터를 담을 수 있는 배열이 포인터배열이다. 이 배열 요소에 또 배열을 꽂으면 2차원 배열이 된다. 위의 numPtrArr 은 2차원 배열인 numArr과 같다. 다만 포인터는 포인터 주소의 크기로 계산되는 반면, 배열은 배열 크기로 계산된다.
#include <stdio.h>
int main(int argc, char *argv[]) {
int nArr[4] = {11, 12, 13, 14};
int (*nArrPtr)[4] = &nArr;
printf("%p: %p, %p\n", nArrPtr, *nArrPtr, nArr);
printf("%zu: %zu, %zu\n", sizeof(nArrPtr), sizeof(*nArrPtr), sizeof(nArr));
printf("%d, %d\n", (*nArrPtr)[1], nArr[1]);
return 0;
}
// 0x7ff7bd7775b0: 0x7ff7bd7775b0, 0x7ff7bd7775b0
// 8: 16, 16
// 12, 12배열포인터는 배열을 포인터로 한 번 더 뺀 것이다. 사실상 *nArrPtr은 nArr과 같다. 다만 포인터의 사이즈는 포인터 주소의 사이즈로 계산되는 반면 배열은 전체 크기로 계산된다.
== 2차원 배열을 배열포인터 할당 ==
자료형 (*포인터이름)[가로갯수];
```c
#include <stdio.h>
int main(int argc, char *argv[]) {
int numArr[3][4] = {
{11, 12, 13, 14},
{21, 22, 23, 24},
{31, 31, 33, 34}
};
// 2차원배열 numArr 은 사실 {요소가4인배열, 요소가4인배열, 요소가4인배열} 이다.
// 2차원배열 numArr 의 주소는 numArr의 0번인덱스의 주소(`요소가4인배열`의 주소)이다.
// int **numPtr = numArr; /*** WRONG 자료형이 다르므로 2차원 배열은 이중포인터에 넣을 수 없다. ***/
// 배열포인터
int (*numPtr)[4]; // `요소가4인배열`을 가리키는 포인터
numPtr = numArr;
printf("%p, %p\n", *numPtr, *numArr);
printf("%d, %d\n", numPtr[2][1], numArr[2][1]);
printf("%zu, %zu", sizeof(numPtr), sizeof(numArr));
return 0;
}
// 0x7ff7bf147590, 0x7ff7bf147590
// 31, 31
// 8, 48
2차원 배열은 사실 배열 포인터를 담고 있는 1차원 배열이다. 따라서 배열포인터로 받을 수 있다.
{11, 12, 13, 14}
▲
│
numArr = {{r0}, {r1}, {r2}}
▲
│
int (*numPtr)[4]
여기서 numPtr과 numArr과 numArr[0]은 같다. 다만 포인터의 사이즈는 포인터 주소의 사이즈로 계산되는 반면 배열은 전체 크기로 계산된다.