Programming/C DataStructure

Array - 배열의 특징

양디 2015. 12. 25. 10:29

Array : 배열

배열은 가장 기초적인 데이터 구조라고 할 수 있다.

기본 변수들을 여러개 동시에 선언하고, 사용한다.


일반적인 변수 10개를 선언한 것과, 10개짜리 배열 1개 선언한 것은 같은 메모리를 차지한다.

그렇지만 그 사용에 있어서 편리함은 천지 차이이고, 이것이 우리가 데이터구조들에 대해 배워야하는 이유가 될 것이다.


배열의 특징


1. 메모리 상에 연속된 여러 변수들이 모여서 하나의 배열을 이룬다.

2. 대괄호[] 내부에 변수의 index를 지정하여 각각의 변수에 접근할 수 있다.

3. 배열의 이름은 배열의 첫번째 변수, 즉 배열[0]의 포인터이다.

4. 선언 할 때에 배열의 크기를 결정하며, 변경할 수 없다.

5. 같은 종류의 변수만 선언 가능하다.


배열은 위의 특징들을 깊이 이해하는 것이 중요하다. 


1번 특징에서 중요한 점은, 메모리 상에 연속된 변수들이라는 것이다.

배열을 선언하게 되면 사용 가능한 메모리 영역 중에서 배열의 사이즈 만큼의 연속된 메모리를 할당받는다. 

따라서 큰 사이즈의 배열을 선언하게 된다면, 해당하는 사이즈 만큼의 메모리 공간이 필요하다.

이것이 왜 문제가 되는가 하면, 다음의 그림들을 한번 봐보자.


그림1. 연속된 메모리 공간

그림2. 불연속 메모리 공간


위의 그림1을 보면, 메모리가 연속으로 2~12까지 11개의 공간이 있다. 

만약 사이즈가 10인 배열을 선언하게 된다면, 문제가 없이 선언이 된다.

그러나 그림2를 보면, 메모리 중간 중간에 사용할 수 없는 공간들이 있다. 

만약 선언하고자 하는 배열의 사이즈가 10인데, 메모리가 그림 2의 상태라면 메모리 할당이 불가능해서 오류가 뜨게 될 것이다.

그러나 연속되어 있기 때문에 관리하기가 편하다는 장점이 되기도 한다.


2번 특징은 배열의 가장 기본적인 사용방식이다. 

1
2
int arr[5= {0,1,2,3,4};
printf("%d", arr[3]);
cs

위와 같은 간단한 배열을 선언하였을 때에, arr[3]과 같은 방식으로 해당하는 index의 변수에 접근할 수 있다.

또한 중요한 점은 배열의 시작은 1번째가 아니라 0번째라는 것이다.

즉 위의 경우에는 arr[0], arr[1], arr[2], arr[3], arr[4]의 5개의 변수가 선언되는 것이다.


3번 특징은 배열의 이름은 배열의 첫번째 변수의 주소값이라는 것인데, 포인터를 잘 이해한다면 이를 이용해서 다양한 응용을 할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
void main() {
 
    int arr[5= { 01234 };
    int* ptr = NULL;
 
    printf("배열에서 2번째 원소 : %d\n", arr[1]);
 
    ptr = arr;
 
    printf("포인터로부터 2번째 원소 : %d\n", ptr[1]);
 
}
cs


위와 같은 코드를 실행해 보면 똑같이 arr 배열의 2번째 원소인 1을 출력한다는 것을 알 수 있다.

8번 라인의 ptr = arr을 통하여 arr[0]의 주소를 ptr에 집어넣었고, ptr은 arr와 같은 int 변수이기 때문에 

10번째 라인처럼 ptr[1]을 통하여 arr[1]의 주소에 접근이 가능하다.

또한 arr[0]의 주소와 arr는 같은 의미이므로, 8번 라인을 

1
ptr = &arr[0];
cs

로 변경하여도 똑같은 방식으로 작동한다는 것을 알 수 있다.


4번 특징의 경우가 배열의 가장 큰 단점이라고 할 수 있다.

배열은 선언할 때에 배열의 크기를 지정해주어야 하며, 한번 선언된 배열은 크기를 늘리거나 줄일 수 없다.

이것은 실제로 코딩을 할 때에 큰 문제가 된다.

변수의 크기가 항상 일정한 경우는 실제로 별로 없다.


예를 들어 MAX_SIZE를 256으로 설정하여 배열을 선언하였다고 할 때에,

256개를 다 쓰면 좋겠지만, 보통 그렇지 않다.

100개 정도의 배열을 사용한다고 치면 나머지 156개의 변수는 메모리만 낭비하고 있는 상황이 된다.

그렇다고 해서 64 사이즈의 배열을 선언한다고 치면, 만약에 더 많은 변수가 필요할 경우 배열을 늘리는 것이 아니라

배열을 새로 선언해서 값을 복사해줘야 하는 일이 생긴다.

이를 Dynamic array라고 하는데, 이는 알고리즘에 관하여 블로깅할 때에 다루도록 하겠다.


따라서 이러한 문제들을 해결하기 위하여 다양한 Data Structure들이 나온 것이다.

다음 장에 나올 Linked List가 가장 기초적인 방법이 되겠다.


5번 특징의 경우도 단점이 되는데, 배열의 모든 변수는 같은 타입의 변수이다.

Int 배열은 int만 저장이 가능하고, long 배열은 long만 저장이 가능한 것이다.

따라서 내용에 다양한 타입의 선언이 필요한 경우에는 사용에 불편함이 생길 수 밖에 없다.

이러한 문제점을 해결한 것이 바로 구조체(Struct)가 되겠다.




댓글