본문 바로가기

C Language/Programming Course

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

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) 만큼 주소가 변할 것입니다.

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

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