프로그래밍 관련/C#

C# 강좌 9편. 배열(Array) [최근 수정 2017.11.26]

LAYER6AI 2018. 1. 12. 14:30


1. 배열(Array)

배열이란, 동일한 타입의 변수를 모아놓은 데이터 집합이라고 말할 수 있습니다. 예를 들어서, 우리가 각 반 학생들의 한 달 독서량을 변수에 담는다고 가정하면 아래와 같이 변수를 선언해야 합니다.

...
    int reading_1 = 4;
    int reading_2 = 9;
    int reading_3 = 1;
    int reading_4 = 0;
    int reading_5 = 21;
    int reading_6 = 12;
...

보기만 해도 비효율적이고, 만약 반에 학생이 30명 정도가 있다면 비슷한 성격의 변수를 똑같이 30번 선언해야 하며, 전체 학생의 독서량을 사용자에게 제공하려고 변수에 접근하여 값을 얻어올 때도 상당히 불편합니다. 여기서, 배열을 사용하면 이 두 문제를 한 번에 잡을 수 있으며, 익숙해지다 보면 여러 개의 데이터를 다루게 될 때 유용하게 사용할 수 있습니다. 아래는 위 문제를 배열로 구현한 예제입니다.

...
    int[] reading = new int[30]{4, 9, 1, 0, 21, 12, ..., ..., ...}
...

상당히 간편해졌죠? 그리고 배열에 접근할 때는 첨자값(index, 인덱스)으로 접근하는데 여기서 주의하실 점은 첨자값은 항상 0부터 시작한다는 사실을 기억하시고 계셔야 합니다. 아래는 첨자값으로 각 배열 요소에 접근하여 그 값을 출력시키는 예제입니다.

...
    Console.WriteLine("reading[0]={0}", reading[0]); // reading[0]=4
    Console.WriteLine("reading[1]={0}", reading[1]); // reading[1]=9
    Console.WriteLine("reading[2]={0}", reading[2]); // reading[2]=1
...

아까처럼 일일이 변수를 선언하여 접근하는 것과는 다르게 배열의 첨자값을 이용한 접근은 상당히 간단합니다. 이제는 직접 배열을 우리가 선언하고, 배운 사실을 응용하여 다른 프로그램을 만들어보도록 합시다. 아래는 배열의 선언 방법입니다.

자료형[] 배열명 = new 자료형[크기];
크기 6을 가진 int 형식의 배열 student를 선언하려면 아래와 같이 선언하시면 됩니다.
int[] student = new int[6];

student[0] = 4;
student[1] = 9;
student[2] = 1;
..

위와 같이 선언하면 아래와 같이 6개의 공간을 가진 int형 배열 구조를 형성합니다.



이제 배열에 대해 기본적인 사항은 알았으니, 배열을 직접 사용해보도록 합시다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] reading = new int[6] { 4, 9, 1, 0, 21, 12 };

            for (int i = 0; i < reading.Length; i++)
                Console.WriteLine("reading[" + i + "]={0}", reading[i]);
        }
    }
}
결과:
reading[0]=4
reading[1]=9
reading[2]=1
reading[3]=0
reading[4]=21
reading[5]=12
계속하려면 아무 키나 누르십시오 . . .
코드의 12행을 보시면 reading이라는 int형 배열이 선언되었고 6개의 공간을 차지합니다. 그리고 그 공간마다 각각 4, 9, 1, 0, 21, 12란 값으로 초기화되었습니다. 11행을 보시면 for문으로 reading의 길이, 즉 크기만큼 반복하여 코드를 실행합니다. 12행에서는 0부터 5까지 접근하여 그 요소가 가지고 있는 값을 출력합니다.


여기서 9행을 다시 살펴보시면, 배열의 선언과 동시에 초기화를 하고 있는데 이방법 말고도, 배열을 선언하는 방법은 더 있습니다. 배열을 선언하고 그와 동시에 초기화를 한다면 아래와 같은 방법도 가능합니다.

int[] reading = {4, 9, 1, 0, 21, 12};

이렇게 코드를 적어도 에러가 나지 않는 이유는, 초기화 시에 배열 요소의 수로 길이가 지정되기 때문입니다. 그렇기에 크기를 생략해도 정상적으로 컴파일이 가능합니다. 위의 코드는 아래의 코드와 같습니다.

int[] reading = new int[]{4, 9, 1, 0, 21, 12};


2. System.Array

Array 클래스는 배열에 대한 다양한 기능을 제공합니다. 여기서, 클래스가 궁금하신 분들은 다음 강좌에서 'C# 강좌 10편. 클래스(Class)'를 미리 살펴보셔도 괜찮습니다. 기능이 상당히 많아, 그것을 모두 다 강좌에서 설명할 수는 없고 주로 쓰이는 메소드와 속성만 간단히 설명하도록 하겠습니다. 이것 말고도 더 궁금하신 분들은 MSDN를 방문하여 참고하시면 됩니다.


MSDN System.Array 관련 문서: http://msdn.microsoft.com/ko-kr/library/system.array.aspx


분류

이름

기능

속성

Rank

배열의 차원 수를 가져옵니다.

Length 

배열의 길이를 가져옵니다.

메소드

Clear

배열 형식에 따라 정수 형식일 경우 0, 논리 형식일 경우 false, 참조 형식일 경우 null으로 초기화됩니다.

ForEach 

지정한 배열의 각 요소에서 지정한 동작을 수행합니다.

Resize 

배열의 요소 수를 지정된 새로운 크기로 변경합니다.

indexOf 

지정한 개체를 검색하여 1차원 Array 전체에서 처음 검색된 개체의 인덱스를 반환합니다.


위의 표는 주로 사용되는 속성과 메소드를 정리한 것입니다. Rank 부터 시작하여 직접 사용하여 어떠한 기능을 하는지 알아보도록 하겠습니다. 아래 예제는 Rank, Length, Clear, ForEach, Resize, indexOf가 사용된 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] reading = new int[] { 4, 9, 1, 0, 21, 12 };

            Console.WriteLine("속성: Rank={0}, Length={1}", reading.Rank, reading.Length);
            // reading의 차원 수와 길이를 반환함

            Console.Write("Clear 메소드: ");
            Array.Clear(reading, 0, 5); // 배열 요소를 0부터 시작하여 5개의 요소를 초기화 시킴
                                        // Array.Clear(요소를 지울 배열, 시작 인덱스, 지울 요소수);
            Array.ForEach<int>(reading, new Action(ShowValue));
            // 해당 배열의 각 요소를 가지고 동작(ShowValue)를 수행함
            // Array.ForEach<데이터타입>(동작을 수행할 배열, new Action<데이터타입>(액션);
            Console.WriteLine();

            Console.Write("Resize 메소드: ");
            Array.Resize(ref reading, reading.Length + 3);
            // reading 배열의 길이를 3만큼 늘림, Array.Resize(배열의 주소값, 새 배열의 크기);
            Array.ForEach<int>(reading, new Action<int>(ShowValue));
            Console.WriteLine();

            Console.WriteLine("indexOf 메소드: {0}", Array.IndexOf(reading, 12));
            // 배열에서 12란 값을 가지고 있는 요소의 인덱스를 반환함
            // Array.IndexOf(배열, 찾고자 하는 값);
        }

        static void ShowValue(int value) // 동작, value를 받아 그 value를 출력시킴
        {
            Console.Write("{0} ", value);
        }
    }
}
결과:
속성: Rank=1, Length=6
Clear 메소드: 0 0 0 0 0 12
Resize 메소드: 0 0 0 0 0 12 0 0 0
indexOf 메소드: 5
계속하려면 아무 키나 누르십시오 . . .
결과를 보아 상당히 유용함을 알 수 있습니다. 코드에 주석을 달아놓았긴 했으나, 각 메소드의 사용 형식을 더 자세히 알고 싶으시다면 MSDN를 방문하여 참고하시기 바랍니다. 

3. 다차원 배열(Multidimensional array)
다차원 배열이란, 말 그대로 여러 개의 차원을 다루는 배열입니다. 우리가 지금까지 만나봤던 배열들은, 모두 가로로만 이루어진 1차원 배열이었습니다. 이번엔 주로 쓰이는 2차원 배열에 대해 알아보도록 하겠는데, 2차원 배열은 1차원 배열과는 달리 가로와 세로를 가지는 평면 구조의 사각형으로 이루어져 있습니다. 


만약에 student란 2차원 배열이 있고 열이 6, 행이 3인 배열이 있다고 합시다. 그렇게 되면 위와 같은 구조를 형성합니다. 1차원 배열의 요소에 접근하는 방법과 2차원 배열의 요소에 접근하는 방법은 비슷합니다. 3열 2행에 있는 값을 가져오고 싶다면, student[2][1]라고 하시면 되겠죠. 아래는 2차원 배열을 선언하는 형식입니다.

자료형[,] 배열명 = new 자료형[행, 열];

이제 2차원 배열을 직접 다루어 컴파일을 해보도록 하겠습니다. 아래 예제는 2차원 배열을 다루는 예제입니다.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] reading = new int[3, 6] { { 4, 9, 1, 0, 21, 12 }, { 1, 4, 6, 0, 9, 5 }, { 4, 4, 2, 4, 0, 0 } };

            for (int i = 0; i < reading.GetLength(0); i++)
                for (int j = 0; j < reading.GetLength(1); j++)
                    Console.WriteLine("reading[" + i + ", " + j + "] = {0}", reading[i, j]);
        }
    }
}
결과:

reading[0, 0] = 4

reading[0, 1] = 9

reading[0, 2] = 1

reading[0, 3] = 0

...

reading[2, 4] = 0

reading[2, 5] = 0

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

코드의 9행을 보시면 reading이라는 2차원 배열이 선언됨과 동시에 초기화를 하고 있고, 그다음에 for문의 중첩이 등장합니다. for문의 조건식에 쓰인 GetLength라는 메소드는 각 차원의 요소 수를 반환하는 메소드입니다. 즉 GetLength(0)은 3이되고, GetLength(1)은 6이 됩니다. 여기선 0부터 차원이 시작합니다. 0은 1차원, 1은 2차원을 의미합니다. 그리고 반복하면서 각 요소의 값을 출력시키고 프로그램이 종료됩니다.


  문자열 사이에 있는 + 연산자는 무엇인가요?


지금까지 배운 바로는 + 연산자는 산술 연산자라고 볼 수 있는데, 피연산자가 정수나 실수가 아닌 문자열이 등장했습니다. 우리가 나중에 배우게 될 개념이지만, 연산자 오버로딩(Operator Overloading)을 통해서 문자열 형식에 대해서도 연산이 미리 정의가 되어 있습니다.


예) "안녕, 내 이름은 " + name + "이야." -----> "안녕, 내 이름은 홍길동이야."


위와 같은 방법은 상당히 작성하기 쉽고, 보기에도 직관적입니다. + 연산자의 피연산자 중 하나가 문자열이고, 다른 하나가 숫자 형식인 경우에도 미리 정의가 되어 있기 때문에 연결할 수 있습니다. 


2차원 배열 말고도, 3차원, 4차원, 5차원.. 배열이 있으나 많이 쓰이지는 않습니다. 복잡하기 때문이죠. 만약에 3차원 배열을 선언하고 싶으시다면 아래와 같은 방법으로 선언하시면 됩니다.

자료형[,,] 배열명 = new 자료형[높이, 세로, 가로];

배열에 대한 설명은 여기서 마치도록 하겠습니다. 수고하셨습니다.


다음 강좌에서는 클래스(Class)에 대해 알아보도록 하겠습니다.