본문 바로가기

Programming Language/C

배열

1. 배열을 사용하는 이유

3개의 정수가 있을 때 가장 큰 정수를 구하는 프로그램을 작성한다고 가정해보겠습니다. 3개의 정수를 변수 3개에 각각 넣어 비교하는 구문을 작성할 것입니다. 그렇다면 정수가 100개가 있을 때는 또 다시 100개의 변수를 만들어야 할까요? 사실 100개 정도 만드는 것 쯤이야 크게 문제될 것은 없습니다만, 솔직히 굉장히 비효율적인 방식이라 부담이 되는 것은 사실입니다. 만약 100,000,000개의 정수가 있다면 사람이 하나하나 변수를 지정하는 것은 불가능한 일입니다. 이러한 경우들에는 동일한 자료형을 여러 개 담는 기술이 필요할 텐데요, 이때 도움이 되는 것이 바로 배열입니다.

다음과 같이 인덱스가 0부터 7까지 있는 배열이 있다고 가정해보겠습니다.

우리가 일반적으로 숫자를 셀 때는 1부터 시작하지만 컴퓨터는 0부터 시작합니다. 배열 또한 마찬가지로 인덱스 번호가 0부터 시작합니다. 따라서 위의 배열은 총 8개의 데이터가 있는 것입니다. 인덱스 0의 값은 7이고 인덱스 1의 값은 6으로, 각각의 인덱스 순서마다 서로 다른 데이터의 값을 정해줄 수 있습니다. 위의 배열에는 정수가 담겨 있으니 자료형을 int로 선언해야 하고, int형 하나의 크기는 4바이트이니 총 32바이트 크기의 배열입니다.


2. 배열의 선언과 초기화

배열의 선언은 다음과 같이 할 수 있습니다.

자료형 배열명[ 배열의 크기 ] = { 초기화 값 };

만약 배열이 총 10개의 데이터가 들어가는 배열이라면, 배열명을 a라 했을 때 a[10]과 같이 표현할 수 있습니다. 초기화 값은 없을 수도 있으며, 배열의 전체 원소를 0으로 모두 초기화하고 싶다면 { 0, } 과 같이 표현하기도 합니다.]

만약 배열의 특정한 데이터에 접근하고 싶을 때는 원하는 데이터의 index 값을 적어주면 됩니다. a[3] = {0, 1, 2} 라는 배열이 있다고 가정해보겠습니다. 이 배열에서 데이터 값 중 하나인 2에 접근하고 싶다면 a[2]라고 적으면 되는 것입니다.

위의 배열 a에서 0의 index는 0, 1의 index는 1, 2의 index는 2입니다.

예제를 통해서 배열을 만들고 개별적인 값에 접근하는 방법에 대해서 이해해보겠습니다.

2.1. 예제1: 배열의 선언과 초기화

#include <stdio.h>

int main(void) {
    int a[10] = { 11,12,13,14,15,21,22,23,24,25 };
    int i;
    for (i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    system("pause");
}

결과:
11 12 13 14 15 21 22 23 24 25 계속하려면 아무 키나 누르십시오 . . .

  • 위 예제에서 배열은 int a[10] = { 11,12,13,14,15,21,22,23,24,25 }; 과 같은 방식으로 초기화를 했습니다.
  • 배열의 크기는 10입니다. 따라서 for문을 i<10 까지 돌려 index 0부터 9까지 돌아가면서 각각의 원소에 접근할 수 있도록 합니다.

위 코드에서 전체 원소를 0으로 초기화한다면 {0,}을 사용하면 됩니다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h>

int main(void) {
    int a[10] = { 0, };
    int i;
    for (i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    system("pause");
}

결과:
0 0 0 0 0 0 0 0 0 0 계속하려면 아무 키나 누르십시오 . . .

2.2. 예제2: 배열의 원소 중에서 최댓값 찾기

배열의 원소 중에서 최댓값을 찾기 전에 먼저 <limits.h> 헤더파일과 INT_MIN 에 대해서 알아보겠습니다.
<limits.h> 헤더파일에는 다양한 자료형들의 최댓값이나 최솟값이 정의가 되어 있습니다. 즉, 각 자료형들의 한계에 해당하는 값들이 포함되어 있는 것입니다. 그리고 INT_MIN은 <limits.h> 헤더파일에 정의된 상수입니다. 약 -20억 정도에 해당하는 수이고, int형으로 나타낼 때 가장 작은 숫자를 표현하고자 할 때 사용합니다. INT_MIN이 존재하듯이 INT_MAX 또한 존재합니다. 더 다양한 정수 제한은 Microsoft Docs의 C및 C++ 정수제한 항목 을 참고하면 좋을 것 같습니다.

그럼 이제 배열의 원소 중에서 최댓값을 찾아보겠습니다.

#include <stdio.h>
#include <limits.h>

int main(void) {
    int a[10] = { 11,12,13,14,100,21,22,23,24,25 };
    int maxValue = INT_MIN;
    for (int i = 0; i < 10; i++) {
        if (maxValue < a[i]) maxValue = a[i];
    }
    printf("%d\n", maxValue);
    system("pause");
    return 0;
}

결과:

100
계속하려면 아무 키나 누르십시오 . . .

for문 안에 있는 if문은 maxValue보다 현재 보고 있는 값이 크다면 maxValue에는 해당 값을 넣어주는 것입니다. 처음 시작할 때 int형으로 표현할 수 있는 숫자 중에서 가장 작은 숫자가 maxValue에 담기기 때문에 for문을 통해서 처음 숫자부터 마지막 숫자까지 돌면서 가장 큰 숫자가 maxValue에 담기는 것입니다. 즉, 100이전까지는 계속해서 새로운 숫자들이 maxValue에 담기다가 100을 접한 뒤로는 다른 숫자가 maxValue에 담기지 않습니다.


3. 문자열과 배열

C언어에서는 자체적인 문자열 자료형을 제공하지 않습니다. 문자열 자체가 문자를 여럿 묶어 놓은 배열이라는 뜻이기 때문에 C언어에서는 문자열을 표현하기 위해서는 배열을 만들어야 합니다. 참고로, C++에서는 이러한 불편함 때문에 자체적으로 string 자료형을 제공하고 있습니다.

C언어에서 'HelloWorld'라는 문자열을 표현하기 위해서는 다음과 같이 배열을 활용합니다.

char a[20] = "HelloWorld"

'HelloWorld'는 문자 하나가 1바이트라는 점을 생각했을 때 10바이트입니다. 따라서 20바이트 크기의 배열은 'HelloWorld'를 담기에는 충분한 크기입니다.
이제, 예제를 통해서 문자열에 대해 알아보겠습니다.

3.1. 예제1

입력받은 문자열을 그대로 출력하는 프로그램입니다. 방금 전 바로 위에서도 말했듯이 문자열을 선언할 때는 문자열의 크기보다 배열의 크기가 크도록 해야 합니다. 이번에도 마찬가지로 HelloWorld를 입력할테니 배열의 크기는 20으로 하겠습니다. 또한 사용자가 직접 문자열을 입력할 것이니 scanf()로 문자열을 받고, 입력과 출력 시 %s 형식 지정자를 사용합니다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
    char a[20];
    scanf("%s", &a);
    printf("%s\n", a);
    system("pause");
}

결과:

HelloWorld
HelloWorld
계속하려면 아무 키나 누르십시오 . . .

3.2. 예제2

문자열로 문자의 배열을 사용하기 때문에 특정 인덱스의 문자에 바로 접근할 수 있습니다. 문자열 같은 경우에는 큰따옴표를 이용해서 바로 초기화가 가능합니다. 크기가 20인 배열 a를 Hello World 문자열로 초기화하고(문자열을 배열a에 받음), 4번째 인덱스를 ', '로 교체해보겠습니다.

#include <stdio.h>

int main(void) {
    char a[20] = "Hello World";
    a[4] = ',';
    printf("%s\n", a);
    system("pause");
}

결과:

Hell, World
계속하려면 아무 키나 누르십시오 . . .

3.3. 예제3

이번에는 문자열에 포함된 'ㅣ'의 개수를 출력해 보겠습니다.

#include <stdio.h>

int main(void) {
    char a[] = "Hello World";
    int count = 0;
    for (int i = 0; i <= 10; i++) {
        if (a[i] == 'l') count++;
    }
    printf("%d\n", count);
    system("pause");
    return 0;
}

결과:

3
계속하려면 아무 키나 누르십시오 . . .

위에서는 배열의 크기를 정해주었지만, 일반적으로 특정한 문자열을 사전에 정의해서 초기화하는 경우에는 정확히 몇 글자인지 명시해주지 않아도 알아서 문자열의 크기에 맞게 배열의 크기가 정해집니다. 'Hello World' 문자열은 띄어쓰기를 포함해서 11자이기 때문에 배열의 크기 또한 11바이트로 설정됩니다. 이에 맞춰 반복문은 10까지 돌 수 있도록 했습니다. 인덱스0부터 인덱스10까지 돌면서 현재 인덱스에 저장된 문자가 'l'인지 검사를 하고 'l'이라면 count의 값을 증가시킵니다.


4. 정리

  • 배열을 사용하면 수많은 데이터에 변수명을 붙이는 등의 번거로운 작업 없이 많은 양의 데이터를 쉽게 처리할 수 있습니다.
  • C언어에서 문자열은 문자의 배열입니다.