SW개발

배열과 포인터(Pointer) 의 상관관계

박종명 2023. 10. 27. 09:15
728x90
이 글은 제가 과거에 운영했던 사이트인 http://dotnet.mkexdev.net 의 글을 옮겨온 것입니다. 원본 글은 2008년 5월일에 작성되었습니다.

그 전에 운영했었던 사이트(mkex.pe.kr)은 흔적도 없이 사라 졌습니다. 그속의 글들도 모두... 그래서 이 사이트도 사라지기 전에 옮기고 싶은 글을 조금씩 이 블로그로 이동시키려 합니다.
(원본글) http://dotnet.mkexdev.net/Article/Content.aspx?parentCategoryID=2&categoryID=9&ID=104

『 배열과 포인터(Pointer) 의 상관관계 』 

배열은 포인터이다

대부분의 프로그래밍 언어에서는 배열이라는 복합 값을 다룰 수 있는 자료구조를 제공한다.
배열과 포인터는 내부적인 처리 방식이 거의 동일하다. 단 배열변수는 상수 포인터 이다

일단 포인터의 내부 구조를 살펴 보자.
아래 샘플 코드는 int 형 변수를 가리키는 포인터를 생성해서 포인터를 통해서 i 의 값을 변경하는 예제이다.

void main(void){      
        int i = 1;
        int *p = &i;
        *p = 2;
        printf("%d",i);
}

 시스템은 내부적으로 변수를 메모리에 저장하고 참조하기 위한 key-value 와 유사한 형태의 Symbol Table 라는 것을 관리한다.  Symbol Table 에는 변수명과 값이 저장된 메모리 주소 그리고 타입정보를 저장한다.

이것은 포인터도 마찬가지이다.

, Symbol Table 에서 포인터는 자신의 타입정보 뿐만 아니라 포인팅하고 있는 대상의 타입정보도 같이 저장한다.

편의상 Symbol Table 가 다음과 같이 구성된다고 가정하자.


위의 예제를 Symbol Table 과 메모리 구조로 표현하면 다음과 같다.

int 형 변수 i  1을 저장했으므로 4byte 메모리 공간에 1을 저장하고 그 주소 값인 0x10 번지를 가리킨다.

그리고 i 의 주소 값을 포인팅 하는 포인터 변수 p 는 역시나 4byte 메모리 공간에 i 의 주소값인 0x10 을 저장하고
있는 0x100 번지를 가리킨다

 포인터 변수가 가리키는 메로리 공간에는  i 의 메모리 주소가 저장되어 있는 것이다(32 bit 시스템에서 메모리 주소 값은 4byte 로 표현되므로 포인터 p  4byte 의 메모리 공간을 차지하게
되는 것이다)

 
.. 그럼 이제 배열을 알아 보자. 다음과 같이 선언된 배열이 있다고 가정하자.

int arr[] = {1,2,3};

 이 배열을 Symbol Table 과 메모리 구조로 표현하면 다음과 같다.

배열 변수인 arr 은 배열의 첫 번째 요소(arr[0]) 를 포인팅 하는 별도의 상수형 메모리 공간인 것이다.

 arr  0x200 을 가리키고 여기에는 배열의 첫 번째 요소(arr[0]) 의 메모리 주소를 포인팅
하고 있는 것이다.
 이 구조는 포인터와 완전히 동일한 구조이다.

실제로 이 배열을 정수형 포인터에 대입하면 포인터를 배열처럼 사용할 수 있다.

void main(void){      
        int arr[] = {1,2,3};
        int *p = arr;
        printf("%d,%d,%d",p[0],p[1],p[2]); //1,2,3 이 출력된다
}

, int *p = arr 은 가능하지만 arr = p 는 성립하지 않는다.
앞서 말했듯이 arr은 상수이기 때문이다. 상수를 변경할 수는 없는 것이다.

 또 하나, 일반적인 포인터에서 *p = 10 하면 p 가 포인팅 하고 있는 곳이 변경된다.

그렇다면 위의 배열 변수를 가지고 *arr = 10 하면 어떻게 되겠는가?
arr 은 배열의 첫 번째 요소를 포인팅하는 포인터이기 때문에 위의 식은 배열의 첫 번째 요소의 값을 변경하게 된다.

void main(void){      
        int arr[] = {1,2,3};
        *arr = 10;
        printf("%d,%d,%d",arr[0],arr[1],arr[2]); //10,2,3 이 출력된다
}

이로써 배열은 포인터 이다 라는 명제를 풀어 보았다.