OneDev

[C] 16. 배열(Array) (1) 본문

Language/C

[C] 16. 배열(Array) (1)

one_dev 2022. 7. 25. 17:08

1. 배열이란?

C 언어에서는 같은 타입의 여러개의 변수를 연속적으로 정의할 수 있는 방법을 제공하고 있는데, 이를 배열(Array)라 한다.

즉 배열은 같은 형(type) 을 가진 변수들의 집합 정도로 생각하면 될 듯 하다.

 

2. 배열의 기초

(1) 배열의 정의

배열을 정의하는 방법은 기본적으로 다음과 같다.

( 배열의 type ) ( 배열의 이름 ) [원소개수];

// 예시
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

위의 예에서 arr 은 int 형 변수 10개를 원소로 가지는 배열인 것이다.

만약 int arr[10] 대신 char arr[10] 이라 썼다면 원소들은 모두 char 형 변수로 선언되었을 것이다.

 

또한, 위의 예에서 처럼 배열의 정이 옆에 = { } (중괄호) 를 해주게 되면 배열 각각의 원소에 중괄호 속 값들이 순차적으로 들어가게 된다. 다만 이 방법은 배열을 정의부분에서만 사용가능하며 이미 정의된 배열에 대해서는 사용이 불가능하다.

int arr[3] = {1,2,3} // 가능
arr[3] ={4,5,6} // 불가능

 

(2) 배열에서의 원소 접근

배열의 각각의 원소에 접근하는 방법은 아래와 같다.

배열의 이름을 적은 뒤 대괄호 [ ] 안에 몇 번째 원소에 접근할지 적어주면 끝이다.

(주의) C언어 에서는 배열의 첫 원소를 0번쨰 원소로 셈한다. 

( 배열 이름 )[ 몇 번째 원소인지 ] //첫번째 원소 = 0, 두 번째 원소 = 1, 세 번째 원소 = 2, .....
// (예시) 컴퓨터는 숫자를 0부터 센다 라고 생각하면 이해가 쉬울듯 하다
arr[0]  => arr 이란 배열의 첫 번째 원소
arr[1] => arr 이란 배열의 두 번째 원소
....
....
arr[n] => arr 이란 배열의 n+1 번째 원소

 

 

3. 배열의 위험성 

먼저 아래의 코드를 보자

#include <stdio.h>

int main(){
	int arr[10] = {1, 2, 3, 4, 5 , 6, 7, 8, 9, 10};
    
    printf("배열의 11번째 원소는? : %d \n", arr[10]);
    
    return 0;
}

위의 코드를 실행시켜봤더니 아래와 같은 결과가 나왔다.

 

이상한 값이 나왔다!

우리는 10개의 원소를 가지는 배열 arr을 정의한 뒤 배열의 11번째 원소를 출력하라는 다소 이상한? 명령을 실행시켜본것이고 결과적으로 엉뚱한 결과값을 출력하게되었다.

왜 이러한 일이 발생했는지 이해하기 위해서는 배열이 메모리 상에서 어떻게 있는지 알 필요가 있다.

 

출처 : 모두의 코드 블로그 / 매번 좋은 자료 감사합니다

 

위의 그림은 배열 arr 이 메모리 상에서 어떠한 형태로 존재하는지 그림으로 나타낸 것이다.

특히 이 그림에서 배열의 시작주소는 0x1234이다.

배열 arr 의 원소들은 int형 데이터 들이므로 한 원소당 4비트의 공간이  할당된것을 볼 수 있다(주소 끝자리 4, 8 , 12=B,....).

앞서 얘기했듯이 C 에서 배열은 (같은 type을 가진)변수들의 단순한 나열이다.

따라서 배열에는 배열의 크기에 관한 정보는 따로 없다.

예를 들면 C는 arr[3] 을 "배열의 처음 위치로부터 네번째 원소" 로 이해한다는 것이다.

 

이제 배열의 끝부분을 살펴보자.

 

출처 : 모두의 코드 블로그

위의 그림처럼 배열의 원소중 arr[9] 가 가장 마지막에 있을것이고, 그 뒤의 메모리 부분에는 배열 arr 과 상관없는 다른 데이터가 들어가 있을 것이다.

이런 상태에서 arr[10] 을 사용한다면 프로그램은 입장에서는 마치 arr[9] 뒤에 arr[10]이 있는 것 처럼 생각해 그 영역의 값을 보여주게 되는 것이다.

만약 해당부분이 접근 불가능한 영역이라면 프로그램은 오류를 내고 종료될 것이고, 아니라면 해당 부분을 사용하고 있는데이터 값이 보여지게 된다.

 

엉뚱한 값을 출력하는  것은 그나마 다행인 일이다.

더 위험한 경우는 해당 부분의 값을 다른 값으로 덮어 씌우는 경우이다.

예를 들어 arr[10] 에 해당하는 변수의 이름을 b 라 하고 b  의 값을 10이라 해보자.

만약 우리가 arr[10] = 3 이라 적는다면 이는 b = 3 과 같은 역할을 하게된다.

이는 배열의 원소를 수정하려다 배열과 상관없는 다른 변수의 값을 바꿔버리는 일인 것이고, 정말 찾기 어려운 버그로 이어질 가능성이 높다.

☆ 따라서 배열을 사용할 떄는 반드시 우리가 참조하는 원소의 위치가 배열의 크기보다 작은지 확인해야 한다.

 

 

 

Comments