[C언어] 배열과 포인터

C언어 포스팅은 '혼자 공부하는 C언어' 책을 보고 공부하고 정리한 것입니다.
내용의 잘못된 부분이나 질문이 있으면 댓글로 남겨주세요!
배열과 포인터의 관계
앞서 정리했듯 배열은 자료형이 같은 변수를 메모리에 연속으로 할당합니다.
그래서 배열의 첫 번째 index의 주소를 알면 나머지 index의 주소도 알 수 있고 모든 배열 요소를 사용할 수 있습니다.
주소는 자료형에 대한 정보를 가지고 있는 값입니다. 정수처럼 보이지만 정수가 아닌 특별한 값입니다.
정수가 아니기 때문에 정해진 연산만 수행할 수 있습니다.
예를 들어 덧셈의 경우,
int array[4];
*(array+0) = 10; //array[0]
*(array+1) = 30; //array[1]
*(array+2) = *(array+1) + 20; //array[1] + 20
scanf("%d", ary + 3); //&array[3]
int형의 배열인 array를 선언했을 때
주소 + 정수는 일반적인 덧셈이 아니라 변수형에 따라 주소의 위치가 달라집니다.
주소 + 정수 -> 주소 + (정수 * int형 크기인 4)가 되어 주소가 바뀌게 됩니다.
예를 들어 array 배열의 시작 주소가 0 일 때 다음과 같이 표현되는 것입니다.
| 포인터 연산식 | 배열 주소 | 배열 요소 표현식 |
| *(array+0) | *(0) | array[0] |
| *(array+1) | *(4) | array[1] |
| *(array+2) | *(8) | array[2] |
| *(array+3) | *(12) | array[3] |
배열을 저장하는 포인터
배열명은 주소이기 때문에 포인터에 저장할 수 있습니다.
int array[4];
int *p = array;
*p = 10;
*(p+1) = 20;
p[2] = p[0] + p[1];
p[3] = 40;
위와 같이 코드를 작성했을 때 만약 array 배열의 주소 값이 50부터 할당되었다면
포인터 p 는 50을 저장하며 첫 번째 배열 index를 가리키는 상태가 됩니다.
*p는 첫 번째 배열 요소를 가리키는 것이며 *(p+1)은 앞서 *(array+1)의 값과 똑같습니다.
p를 array의 주소로 가리켰기 때문에 p도 배열처럼 p[ ] 형태로 사용할 수 있습니다.
표와 같이 네 개의 표현이 같은 표현입니다.
| pa[2] = pa[0] + pa[1] | *(pa+2) = *(pa+0) + *(pa+1) | *(ary+2) = *(ary+0)+ *(ary+1) | array[2] = array[0] + array[1] |
결국, 포인터에 배열명을 저장하면 포인터 연산을 통해 배열을 사용할 수 있고
포인터를 배열명처럼 사용할 수 있습니다.
배열명과 포인터 차이
- 차이점 1 sizeof 크기가 다릅니다.
int array[5];
int *p = array;
sizeof(array); // 20바이트 - 배열 전체 크기
sizeof(p); // 4바이트 - 포인터 하나의 크기
- 차이점 2
포인터는 변수, 배열명은 상수입니다.
배열명은 주소이므로 상수인데, 포인터는 주소 값을 가지는 변수 이므로 값을 변화할 수 있습니다.
이렇게 배열과 포인터의 관계를 공부한 것을 정리해봤습니다.
틀린 부분이나 질문이 있으면 댓글로 남겨주세요
다음 포스팅으로 찾아오겠습니다 :)