문자열 배열과 포인터 배열의 차이점
아래의 수식이 왜? 불가능할까?
&ar, ar 을 출력해보면 아마도 같은 값이 나오는 것을 볼 수 있을 것이다. 어찌보면 이 둘은 같아보이지만 틀리다.
ar 은 포인터 상수로 정확한 타입은 int* const 이다.
&ar은 크기가 5인 정수형 배열이며 타입은 int(*)[5] const 이다.
int ar[5] = {1,2,3,4,5};
int *pi;
pi = ar; // 가능
pi = &ar; // 불가능
고로 &ar 은 배열 전체에 대한 주소이기 때문에 pi 포인터 상수에 대입하려고 할 때 오류가 나는 것이다.
해결 방법은 아래와 같이 수정해야 대입을 할 수 있다.
int (*pi)[5];
pi = &ar;
여기서 (*pi)[5] 와 *pi[5] 는 굉장히 다르다.
요약 ( Summary )
<포인터 배열> : 포인터를 배열로 나열한 것이다.
int i, arr_len;
int num01 = 10, num02 = 20, num03 = 30;
int* arr[3] = {&num01, &num02, &num03}; // int형 포인터 배열 선언
<배열 포인터> : 배열을 가르키는 포인터.
배열의 이름은 그 값을 변경할 수 없는 상수라는 점을 제외하면 포인터와 같다고 했습니다.
이렇게 배열 이름이 있는데도 따로 배열 포인터를 정의하여 사용하는 이유는 2차원 이상의 배열을 가리킬 때 포인터를 통해 배열과 같은 인덱싱을 할 수 있도록 하기 위함입니다.
즉, 포인터를 배열처럼 사용하기 위해서 배열 포인터를 정의하여 사용합니다.
따라서 배열 포인터는 1차원 배열에서는 아무런 의미가 없으며, 2차원 이상의 배열에서만 의미를 가집니다.
int arr[2][3] = // 배열의 선언
{
{10, 20, 30},
{40, 50, 60}
};
int (*pArr)[3] = arr // 배열 포인터의 선언
// 함수에서 사용
void printArr(int(*pArr)[4],int row,int col) {
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++)
printf("%d ", pArr[i][j]);
printf("\n");
}
}
// Ex.2
void printArr(int pArr[][4],int row,int col) {
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++)
printf("%d ", pArr[i][j]);
printf("\n");
}
}
여기서 pArr[][4] == (*pArr)[4] 는 동일하다.
포인터 배열과 배열 포인터 구분!
1. int (*pArr)[3];
2. int* pArr[3];
위의 예제 중에서 첫 번째는 int형 데이터를 저장할 수 있는 2차원 배열을 가리키는 배열 포인터입니다.
하지만 두 번째는 int형 데이터를 가리킬 수 있는 포인터 변수를 모아 놓은 배열을 가리키는 포인터 배열이 됩니다.
따라서 괄호의 유무가 중요하다.
(+ 추가적으로)
이전에 문자열 포인터와 배열 포인터의 차이점에 대해서 알아보았는데
문자열 포인터의 경우에는 메모리가 읽기 전용으로 저장이 되기 때문에 각 요소에 대한 접근은 가능하지만 수정은 하지 못했다.
이를 해결한 것이 바로 동적할당 malloc 이다.
'C 언어' 카테고리의 다른 글
C언어 0.08 - 동적할당 (0) | 2021.10.30 |
---|---|
C 언어 0.07 - bool 자료형 (0) | 2021.10.30 |
C 언어 0.05 - 포인터 ( pointer ) (0) | 2021.10.30 |
C 언어 0.04 - 배열 ( array ) (0) | 2021.10.30 |
C 언어 0.03 - 문자열 ( string ) (0) | 2021.10.27 |