'배열'에 해당되는 글 1건

  1. 2006/12/20 C/C++ - 배열과 포인터의 관계

C/C++ - 배열과 포인터의 관계

Programming 2006/12/20 05:07
int arr[5]; // 배열 선언

위 코드는 int형 메모리 공간을 다섯 개 만들어 주는 배열 선언이다.
그리고 위 코드를 실행하게 되면, 아래의 그림과 같이 메인 메모리에 20byte의 메모리를 할당 받게 된다.



int형 데이터 타입은 4byte의 메모리를 차지하기 때문에
위의 그림에서와 같이, 메모리 주소는 4만큼 차이가 난다.
이것을 일반적으로 오프셋(OffSet)이라고 한다.

① 오프셋(OffSet)과 인덱스의 관계

배열의 첫 번째 원소를 참조하기 위해서 아래와 같은 코드를 쓴다.

arr[0]; // 1 번째 원소의 내용을 참조
 

여기서 인덱스는 오프셋과 많은 연관이 있다.
첫 번째 원소를 참조하기 위해 사용되어진 인덱스 0은
arr라는 배열의 시작 주소로 부터 Offset(0) 라는 의미
가 된다.
그리고 시작 주소로부터 OffSet(0) 만큼 떨어진 주소에서 4byte 크기 만큼 메모리의 내용을 읽어 온다.

arr[1]; // 2 번째 원소의 내용을 참조
위와 동일하게 배열의 시작 주소로 부터 Offset(4) 이라는 의미가 된다.
시작 주소로부터 OffSet(4) 만큼 떨어진 주소에서 4byte 크기 만큼 메모리의 내용을 읽어 온다.
그리고 OffSet 계산 법은 다음과 같다. ((sizeof(int) * 1);),

arr[2]; // 3 번째 원소의 내용을 참조
위와 동일하게 배열의 시작 주소로 부터 Offset(8) 이라는 의미가 된다.
시작 주소로부터 OffSet(8) 만큼 떨어진 주소에서 4byte 크기 만큼 메모리의 내용을 읽어 온다.
그리고 OffSet 계산 법은 다음과 같다. ((sizeof(int) * 2);), 이라는 의미가 된다.

arr[3]; // 4 번째 원소의 내용을 참조
위와 동일하게 배열의 시작 주소로 부터 Offset(12)  이라는 의미가 된다.
시작 주소로부터 OffSet(12) 만큼 떨어진 주소에서 4byte 크기 만큼 메모리의 내용을 읽어 온다.
그리고 OffSet 계산 법은 다음과 같다. ((sizeof(int) * 3);), 이라는 의미가 된다.

arr[4]; // 5 번째 원소의 내용을 참조
위와 동일하게 배열의 시작 주소로 부터 Offset(16) 이라는 의미가 된다.
시작 주소로부터 OffSet(16) 만큼 떨어진 주소에서 4byte 크기 만큼 메모리의 내용을 읽어 온다.
그리고 OffSet 계산 법은 다음과 같다. ((sizeof(int) * 4);), 이라는 의미가 된다.

※ cl 컴파일러를 쓰는 Microsoft사의 Visual C++은 정적 배열을 선언 할 때 배열 원소들을 0xcccccccc
  로 초기화 시킨다.

② 배열과 포인터의 관계

int arr[i];
 

위의 arr 배열의 시작 주소를 알아 내면 OffSet연산을 통해 배열의 원소값을 참조 할 수 있다.
포인터는 메모리의 주소를 담을수 잇는 변수 이며, 포인터의 주소 연산을 통해 주소 값을 증가, 또는 감소 시킬 수 있고, 내용 참조 연산을 통해 주소가 지시하는 메모리의 내용을 참조 할 수 있다 .

배열의 시작 주소는 배열의 이름 이다.
int* pt = arr; // 배열의 시작 주소를 포인터 변수 pt에 저장

배열의 인덱스 연산 : 시작 주소 위치 + Offset
포인터의 주소 연산 : 시작 주소 위치 + Offset

pt + i; // i 번째 원소에 접근
위 코드는 배열의 시작 주소로 부터 i 만큼 떨어 진 메모리의 위치 이다.
여기서 OffSet의 계산법도 앞서 설명한 방법과 동일 하다. (sizeof(int) * i;)

포인터의 내용 참조 연산은 포인터 변수 앞에 "*"만 붙여 주면 포인터의 데이터 타입 크기의 만큼의 메모리를 참조 할 수 있다.

*(pt + i); // i 번째 원소의 내용을 참조

arr + 0 == pt + 0;     arr[0] == *(pt + 0);
arr + 1 == pt + 1;     arr[1] == *(pt + 1);
arr + 2 == pt + 2;     arr[2] == *(pt + 2);
arr + 3 == pt + 3;     arr[3] == *(pt + 3);
arr + 4 == pt + 4;     arr[4] == *(pt + 4);

위의 코드에서 보여 지는 바와 같이 포인터와 배열은 동일한 방법으로 처리되어 진다.
즉, 포인터와 배열은 같다.
단지 내용 참조를 할 때 written 코드만 틀리다.

배열의 이름은 상수 포인터 이다.
  일반적인 포인터는 포인터 변수이다.


arr = arr + i; //정적 배열은 시작 주소가 고정, 즉 상수 값
               // 컴파일 시키면 에러
pt = pt + i;  //포인터로 만든 배열은 시작 주소가 바뀔 수 있다, 즉 변수 값
 

32bit 컴퓨터에서는 주소는 4byte로 표현, 64bit 컴퓨터에서는 주소는 8byte로 표현 되어진다.
sizeof(pt); // 주소의 크기 확인
Creative Commons License
Creative Commons License
명언 한마디
건강이 육체와 관련이 있듯, 정성과 마음을 다하는 태도는 영혼과 관계가 있습니다.
톨스토이
top