C Language/Programming Course

6장 배열(2부 배열의 주소 체계) 첫번째 시간

행복하면 2009. 11. 11. 18:19

6장 배열

2부 배열의 주소 체계

 

이번시간에는 저번 시간에 배운 배열이 메모리 상에 어떻게 올라가는지 볼려고 합니다.
여기서 나오는 메모리 같은 경우는 배열만 생각하여 그린 메모리입니다.

먼저 배열에 대해서 복습을 해 볼까요!?
저번 시간에는 여관으로 예를 들었는데, 이번에도 이해가 쉽게 그렇게 예를 들겠습니다.

 101호 102호  103호  104호 

이렇게 1층에 방이 4개가 있습니다.
럼 이 방 4개를
1차원 배열로 표현을 해 보고 배열이 아닌 각각의 변수로 표현을 해 보겠습니다. 

=============================================
int one_room[4]; // 배열표현
int _101ho, _102ho, _103ho, _104ho; // 일반 변수 표현
=============================================

이렇게 두가지로 표현을 하였습니다.
그럼 이렇게 정의를 하면 메모리 상에는 어떻게 만들어 지는지 보겠습니다.

먼저 배열이 어떻게 메모리상에 저장이 되는지를 보면
 

 0x10000  
 0x10004  
 0x10008 one_room[0]
 0x1000c one_room[1] 
 0x10010 one_room[2]
 0x10014 one_room[3]
 0x10018  
 0x1001c  

이런 식으로 저장이 됩니다. 여기에서 왼쪽부분은 주소를 나타내었는데
실제로 저 주소에 저장이 되는 것이 아니라 저런식으로 연속으로 저장된다는 것만
보시면 됩니다.
그리고 그냥 일반 변수로 만들게 되면,

 0x10000 _101ho
 0x10004  
 0x10008 _103ho
 0x1000c
 0x10010
 0x10014 _102ho
 0x10018 _104ho
 0x1001c  

이런 식으로 순서가 없이 메모리 상에 자리를 잡게 됩니다. 

이것 두 표를 보게 되면 확실하게 배열이 일반 변수와 어떻게 다른지 봤을 것입니다. 
그리고 조금 응용을 한다면 배열의 처음 주소만을 가지고 다른 다음 배열로 이동도 
가능할 것이라는 것도 대충 짐작을 할 수 있을 것입니다. 

소스를 보면서 계속 설명을 하겠습니다. 
=====================================
int room[4];

room[0] = 1;
room[1] = 2;
room[2] = 3;
room[3] = 4;

printf(" %d\n", room[0]);
printf(" %d\n", &room[0]);
printf(" %d\n", room);
====================================

먼저 이 소스의 출력문에서 답이 어떻게 나올 것 같은지 한번 생각해 보시길 바랍니다.
답을 본다면
첫번째 출력문은 1이 출력 될것이고
두번째 출력문은 room 배열의 시작주소가 표시 됩니다.
즉, 일반 변수 처럼 변수명에 '&' 이 기호만 붙이면 주소가 출력 된다는 것입니다.
여기에서 또 다르게 주소를 알 수 있는 방법이 있는데
그 방법은 바로 세번째 출력문입니다.
이는 room이라는 배열의 시작 주소가 출력이 되게 됩니다.

그럼 &room[1]을 출력시킨다면 어떻게 될까요!?
이제 실제로 출력을 해본다는 생각으로 다시 설명을 해 보겠습니다.
이 설명을 위해 위 배열 표를 한번 더 써 보도록 하겠습니다.

 0x10000  
 0x10004  
 0x10008 one_room[0]
 0x1000c one_room[1] 
 0x10010 one_room[2]
 0x10014 one_room[3]
 0x10018  
 0x1001c  

=====================================
int one_room[4];

one_room[0] = 1;
one_room[1] = 2;
one_room[2] = 3;
one_room[3] = 4;

printf(" %d\n", &one_room[0]);
printf(" %d\n", one_room);
printf(" %x\n", &one_room[1]);
printf(" %x\n", one_room+1);
printf(" %x\n", &one_room[2]);
printf(" %x\n", one_room+2);
printf(" %x\n", &one_room[3]);
printf(" %x\n", one_room+3);
====================================

이 출력문의 답을 한번 생각해 보세요
주소는 위 표로 생각을 해 보시고..

답을 먼저 보여 드리겠습니다.
====================================
0x10008
0x10008
0x1000c
0x1000c
0x10010
0x10010
0x10014
0x10014
====================================
이렇게 답이 나오게 됩니다.
&one_room[0], &one_room[1], &one_room[2], &one_room[3]
이 부분은 대충 이해가 가실 것이라 생각 되는데

one_room, one_room+1, one_room+2, one_room+3
이 부분이 조금 새롭게 보일 것입니다.

나중에 포인터를 하면서 다시 새롭게 설명을 할 것인데,
간단하게 설명을 한다면
위에서 one_room이라고 출력을 하게 한다면 배열의 시작주소를 출력 하게 된다고 하였습니다.
그럼 상식적으로 생각을 한다면 +1이 붙는다면
그 주소에 +1 즉 10000이라면 10001이 되어야 되는데
10004가 되니 조금 헷갈려 하실 것입니다.
이는 이렇게 생각하시면 됩니다.
+1이라는 것이 숫자1을 나타내는 것이 아니라 배열[1]이라고 생각을 하시면
됩니다.
즉, one_room 배열의 바로 뒤의 위치를 나타낸다는 것입니다.

그럼 주소가 얼마 변한다는 것이냐를 알기 위해서는
이 배열이 int형이기 때문에
sizeof(int) 만큼 주소가 변한다는 것입니다.
만약 char형으로 배열을 만들었다면
sizeof(char) 만큼 주소가 변할 것입니다.

대충 이해가 가셨는지 모르겠네요.
이 부분은 포인터 부분과 겹치는 부분이라 자세히는 설명을 드리지 않겠습니다.

나중에 포인터 부분을 하게 된다면 다시 설명을 드리도록 하겠습니다.
이번시간에는 이것으로 마치고 다음시간에 다차원 배열에 대해서 설명을 드리도록 하겠습니다.