C# 강좌 9편. 배열(Array) [최근 수정 2017.11.26]
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]);
}
}
}
여기서 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);
}
}
}
만약에 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)에 대해 알아보도록 하겠습니다.