The Pawn language - CompuPhase

배열

개요

본 챕터에서는 배열(Array)에 대해서 다룹니다. 여러모로 자주 사용되는 기능이므로 꼭 숙지하시기 바랍니다.

배열이란 순서대로 나열해 놓음을 의미합니다. 왜 배열을 사용해야 할까요? 여러가지 이유가 있는데 우선 다음 예제를 통해 이해해 보겠습니다.

배열을 사용하지 않은 예제

한 학급이 있다고 가정합니다. 학급 안에는 10명의 학생이 있습니다. 그리고 5과목(국어,영어,수학,사회,과학)이 있습니다. 이들의 성적표를 프로그래밍으로 작성하고자 합니다. 아래 코드와 같이 작성할 수 있습니다.

new student_1_korean = 100;
new student_1_english = 95;
new student_1_math = 72;
new student_1_social = 33;
new student_1_science = 78;

new student_2_korean = 35;
new student_2_english = 88;
new student_2_math = 67;
new student_2_social = 59;
new student_2_science = 70;

new student_3_korean = 25;
new student_3_english = 79;
new student_3_math = 80;
new student_3_social = 99;
new student_3_science = 47;

// ...

new student_10_korean = 83;
new student_10_english = 54;
new student_10_math = 97;
new student_10_social = 57;
new student_10_science = 55;

참으로 안타까운 일이 아닐 수 없습니다. 학생 10명 X 5과목 = 50개의 변수가 필요합니다. 심지어 각 학생의 평균 점수를 구하려면 아래와 같이 해야 합니다.

new student_1_average = (student_1_korean + student_1_english + student_1_math + student_1_social + student_1_science) / 5;
new student_2_average = (student_2_korean + student_2_english + student_2_math + student_2_social + student_2_science) / 5;
new student_3_average = (student_3_korean + student_3_english + student_3_math + student_3_social + student_3_science) / 5;
new student_4_average = (student_4_korean + student_4_english + student_4_math + student_4_social + student_4_science) / 5;
new student_5_average = (student_5_korean + student_5_english + student_5_math + student_5_social + student_5_science) / 5;

아주 미쳐버릴 일입니다. 학생이 100명이라면 어떻게 될까요? 이렇게는 더 이상 안되겠습니다. 이럴 때 배열을 사용해야 합니다.

1차원 배열: 예제 1 (선언)

우선 쉬운 예제를 위해서 1과목만 있다고 가정합니다. 학생 10명의 점수를 저장하는 배열을 만들어 보겠습니다.

new score[10];

네... 끝입니다. 10개의 변수를 한 줄로 생성하였습니다. 그럼 사용은 어떤 식으로 할까요?

score[0] = 100;
score[1] = 58;
score[2] = 99;
score[3] = 87;
...
score[9] = 97;

이런 식으로 숫자를 이용하여 배열에 접근할 수 있습니다. 괄호 [ ] 안에 들어가는 숫자를 인덱스(index)라고 하며, 이러한 접근을 인덱싱(indexing)이라고 합니다.

인덱스는 0부터 시작한다는 특징이 있습니다. 위 예제에서는 score 배열의 크기가 10 입니다. 따라서 인덱스는 0~9까지의 범위를 갖습니다.

1차원 배열: 예제 2 (초기화)

예제 1에서는 10명의 학생의 점수를 입력하는 데 10줄의 코드를 사용했습니다. 이를 한 줄로 작성하여 초기화를 한다면 다음과 같습니다.

new score[10] = {100,58,99,87,40,12,67,95,42,97};

만약 배열 크기보다 적게 입력하여 초기화 할 경우, 입력하지 않은 부분은 0으로 초기화 됩니다.

new score[10] = {100,58,99}; // score = 100, 58, 99, 0, 0, 0, 0, 0, 0, 0

1차원 배열: 예제 3 (초기화, Progressive initiallers)

이번에는 조금 고급스러운(?) 초기화 방법에 대해서 배웁니다. 그것은 " ... " 기호를 사용하여 초기화 하는 방법입니다. 이 기호를 사용하면 앞의 값을 참조하여 뒤의 입력되지 않은 부분을 적절하게 초기화 해 줍니다.

new a[10] = { 5, ... }; // 모든 값이 5로 설정됨
new b[10] = { 1, 2, ... }; // b = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
new c[8] = { 1, 2, 40, 50, ... }; // c = 1, 2, 40, 50, 60, 70, 80, 90
new d[10] = { 10, 9, ... }; // d = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

배열 a는 모든 값이 5로 초기화 됩니다.

배열 b는 1, 2, ... 를 입력하였으므로 1씩 증가하는 규칙으로 초기화 됩니다.

배열 c는 마지막 규칙인 40, 50, ... 에 따라 10씩 증가하는 규칙으로 초기화 됩니다.

배열 d는 10, 9, ... 규칙에 따라 1씩 감소하는 규칙으로 초기화 됩니다.

2차원 배열: 예제 1 (선언 및 사용)

위 예제까지는 학생 당 1과목의 점수만 저장했습니다. 이제 원래대로 학생 당 5과목을 저장하려고 합니다. 즉, 두 개의 그룹(?)이 생기게 되는데, 학생 10개와 과목 5개 입니다. 이를 배열로 표현하면 아래와 같습니다.

new score[10][5];

학생의 출석 번호가 0~9라고 가정합니다. 5번 학생의 점수를 입력하고 싶으면 아래와 같이 하면 됩니다.

// score[학생][과목]

score[5][0] = 100;
score[5][1] = 90;
score[5][2] = 85;
score[5][3] = 95;
score[5][4] = 70;

2차원 배열: 예제 2 (반복문 사용)

이번에는 3번 학생의 평균 점수를 알고 싶습니다. 두 가지 방법으로 구할 수 있는데, 그냥 하는 방법과 반복문을 이용하는 방법입니다.

new Float:average;

// 방법 1: 그냥 한다
average = (score[3][0] + score[3][1] + score[3][2] + score[3][3] + score[3][4]) / 5;

// 방법 2: 반복문 사용
for(new i=0; i<5; i++)
    average += score[3][i];
average /= 5;

배열과 반복문의 조합은 아주 유용합니다. 방법 2를 보시면 반복문을 통해 5과목의 점수를 모두 average 변수에 합산합니다. 그리고 반복문이 끝나면 합산된 점수를 5로 나눠 평균을 구하게 됩니다.

만약 과목 수가 늘어나거나 줄어든다면 방법 1은 코드를 많이 수정해야 할 것입니다. 하지만 방법 2는 for 문의 조건만 변경하면 되므로 훨씬 효율적이라고 할 수 있습니다.

2차원 배열: 예제 3 (이중 반복문 사용)

이번에는 학급의 평균을 알고 싶습니다. 학급 평균은 각 학생들의 평균 점수를 모두 더해서 학생 수로 나눠 구할 수 있습니다. 그렇다면 두 가지의 작업을 진행해야 합니다.

  1. 각 학생의 평균 점수 구하기 (과목 점수를 모두 더해서 5로 나누기)
  2. 학급의 평균 구하기 (학생 점수를 모두 더해서 10으로 나누기)

이는 이중 반복문을 이용하여 구현할 수 있습니다.

new Float:average_class;
new Float:average_student;
for(new i=0; i<10; i++) // 모든 학생에 대해
{
    average_student = 0.0;
    for(new j=0; j<5; j++) // 모든 과목에 대해
        average_student += score[i][j];
    average_student /= 5; // 학생 [i]의 평균 점수

    average_class += average_student;
}
average_class /= 10; // 학생들의 평균 점수(= 학급 평균)

다소 복잡하지요? 천천히 읽어보시면서 이해해 보시기 바랍니다.

2차원 배열: 예제 4 (초기화)

2차원 배열을 초기화 하는 방법은 1차원 배열과 유사합니다.

new a[4][3];
new b[3][2] = { {1,2}, {3,4}, {5,6} }; 
new c[3][3] = { {1}, {2,...}, {3,4,...} }; // { {1,0,0}, {2,2,2}, {3,4,5} }

댓글

댓글 본문
  1. b[0] = {1,2};
    b[1] = {3,4};
    b[2] = {5,6};
    입니다.
    대화보기
    • 5과목의 점수를 전부 더해야 하는데, 변수를 0.0으로 덮어쓰지 않으면 기존 학생의 점수가 남아있게 됩니다.
      대화보기
      • 준영
        2차원 배열 초기화에 대해 보충이 필요합니다.
        이해가 되지 않습니다.

        new b[3][2] = { {1,2}, {3,4}, {5,6} };

        아까 처럼 학생을 예로 든다면

        new b[3][2] = { {1,2}
        [3] 3번 학생의 2번 과목을...

        잘 모르겠네요...
      • 준영
        for(new i=0; i<10; i++) // 모든 학생에 대해
        {
        average_student = 0.0;

        여기서 average_student = 0.0; 이건 뭔가요?
      • 준영
        1번 읽음.