C# 언어에서 배열은 동일한 데이터 형식을 가진 여러 요소를 담을 수 있는 데이터 구조입니다. 배열은 고정된 크기를 가지며 인덱스를 사용하여 각 요소에 접근할 수 있습니다.
1. 개념
배열은 동일한 데이터 형식을 가진 여러 요소를 순서대로 저장하는 자료구조로, 각 요소는 고유한 인덱스를 가지고 있습니다. 배열은 선언 후에 크기를 변경할 수 없으며, 크기는 배열을 생성할 때 결정됩니다.
2. 형식
배열의 기본 문법은 아래와 같습니다.
변수타입[] 변수명 = new int[데이터를 담을 크기]
// 형식1: 데이터형[] 배열이름;
int[] myArray;
// 형식2: 배열 초기화
int[] myArray = new int[5]; // 크기가 5인 int형 배열 생성
// 형식3: 초기값을 가진 배열
int[] myArray = { 1, 2, 3, 4, 5 };
배열 선언법은 변수 타입에 대괄호( [ ] )를 감싸주고, 뒤에는 초기 값 대신, 객체 선언 방법과 같이 new 키워드를 써 준 후 변수 타입을 다시 명시해 주고, 얼마큼의 데이터를 담을지 배열의 크기를 지정해 줍니다.
3. 활용
3.1 배열 요소에 접근
int[] myArray = { 1, 2, 3, 4, 5 };
int element = myArray[2]; // 인덱스 2에 있는 요소에 접근 (값은 3)
배열은 1이 아닌 0부터 시작합니다. myArray[2]의 값은 2가 아닌 세 번째 값인 3이 됩니다.
3.2 배열의 길이 확인
int[] myArray = { 1, 2, 3, 4, 5 };
int length = myArray.Length; // 배열의 길이를 확인 (값은 5)
배열로 선언된 변수는, Length라는 함수를 제공해 줍니다. 이 함수는 배열의 크기를 알려주는 매우 중요한 함수입니다.
데이터의 크기를 5로 정했으면 5를 리턴해 주고, 10으로 정했으면 10을 리턴해 줍니다.
4. 사용 예
4.1 반복문과 함께 사용
int[] numbers = { 1, 2, 3, 4, 5 };
// for문을 사용하여 배열의 요소 출력
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
// foreach문을 사용하여 배열의 요소 출력
foreach (int number in numbers)
{
Console.WriteLine(number);
}
4.2 다차원(N차원) 배열
int[,] matrix = new int[3, 3] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
// 이중 for문을 사용하여 다차원 배열의 요소 출력
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write(matrix[i, j] + " ");
}
Console.WriteLine();
}
다차원 배열은 많이 사용하지는 않지만, 2차원 이상의 배열을 말합니다.
대부분 배열은 1차원으로 시작해서 2차원까지 사용하는 것을 권장합니다.
2차원 배열의 데이터 선언 방법은 아래와 같습니다.
변수타입[][] 변수명 = new 변수타입[X축 배열크기][Y축 배열크기];
1차원 배열과의 차이는 대괄호가 2개씩 묶여 있다는 것입니다. 더 많은 차원의 배열은 대괄호의 개수가 더 늘어납니다.
5. 배열의 간단한 예제
배열을 활용하여 학생들의 성적을 저장하고 평균을 계산하는 기능을 구현한 간단한 예제입니다.
using System;
class Program
{
static void Main()
{
// 학생 성적을 저장할 배열
int[] grades = new int[5];
// 학생 성적 입력 받기
for (int i = 0; i < grades.Length; i++)
{
Console.Write($"학생 {i + 1}의 성적을 입력하세요: ");
grades[i] = Convert.ToInt32(Console.ReadLine());
}
// 학생 성적 출력
Console.WriteLine("\n입력한 학생 성적:");
for (int i = 0; i < grades.Length; i++)
{
Console.WriteLine($"학생 {i + 1}: {grades[i]}");
}
// 평균 계산
double average = CalculateAverage(grades);
Console.WriteLine($"\n성적 평균: {average:F2}");
}
// 평균 계산 함수
static double CalculateAverage(int[] grades)
{
int sum = 0;
foreach (int grade in grades)
{
sum += grade;
}
return (double)sum / grades.Length;
}
}
5명의 학생 성적을 입력받고, 입력한 성적을 출력한 뒤에 그 성적의 평균을 계산하여 출력하는 간단한 예제입니다.
grade 배열을 사용하여 학생들의 성적을 저장하고 CalculateAverage 함수를 통해 배열의 평균을 계산합니다.
출력 결과는 아래와 같습니다.
학생 1의 성적을 입력하세요: 80
학생 2의 성적을 입력하세요: 90
학생 3의 성적을 입력하세요: 75
학생 4의 성적을 입력하세요: 85
학생 5의 성적을 입력하세요: 95
입력한 학생 성적:
학생 1: 80
학생 2: 90
학생 3: 75
학생 4: 85
학생 5: 95
성적 평균: 85.00
6. 배열 사용 시 주의점
- 인덱스 범위 확인:
- 배열의 인덱스는 0부터 시작합니다. 따라서 유효한 인덱스는 0부터 배열의 길이보다 1 작은 값까지입니다. 인덱스를 벗어나는 접근은 예외를 발생시키므로 주의해야 합니다.
- 배열의 길이 고정:
- 배열은 생성 시에 크기가 고정되기 때문에 크기를 동적으로 변경할 수 없습니다. 필요에 따라 동적 배열 또는 다른 데이터 구조를 고려해야 할 수 있습니다.
- Null 처리:
- 배열은 참조 타입이기 때문에 초기화되지 않으면 기본적으로 null로 초기화됩니다. 사용 전에 배열을 명시적으로 초기화하거나 값 할당을 해야 합니다.
- 다차원 배열 처리:
- 다차원 배열을 다룰 때 각 차원의 길이를 고려해야 합니다. 각 차원의 크기가 일치해야 합니다.
- 배열 복사:
- 배열을 복사할 때 얕은 복사와 깊은 복사의 개념을 이해해야 합니다. Array.Copy 또는 Array.Clone 등의 메서드를 사용하여 복사할 수 있습니다.
- 배열의 성능 고려:
- 배열의 크기가 크거나 배열을 자주 변경해야 하는 경우에는 성능에 영향을 줄 수 있습니다. 이러한 경우에는 다른 데이터 구조를 고려해야 할 수 있습니다.
- C#의 다양한 컬렉션 사용:
- 배열 이외에도 C#은 다양한 컬렉션을 제공합니다. 필요에 따라 List<T>, Dictionary<K,V>, Queue<T>, Stack<T> 등을 고려해 보세요.
- 예외 처리:
- 배열을 사용하는 코드에서 예외 처리를 고려해야 합니다. 예를 들어, 배열의 길이를 벗어난 인덱스에 접근하려고 할 때 발생하는 예외를 처리해야 합니다.
배열을 사용할 때는 위와 같은 주의점을 고려하여 안정성과 성능을 고려하는 것이 중요합니다.
7. Arraylist : 데이터가 얼마나 담길지 예측이 불가능한 경우
ArrayList은 C#에서 제공하는 동적 배열 기반의 컬렉션 클래스입니다. 배열과 달리 크기가 동적으로 조절 가능하며, 객체의 추가 및 제거가 용이합니다.
컬렉션이란, 간단히 말해 자료구조(Data Structure)입니다. 자료구조란 자료를 효과적으로 이용할 수 있도록 컴퓨터에 저장하는 방법입니다.
C#에서는 이러한 자료구조를 표현하는 컬렉션에는 배열(Array), 스택(Stack), 큐(Queue) 등이 있습니다.
이러한 컬렉션을 사용하기 위해서는 using 구문에 System.Collections 라는 네임스페이스 사용을 선언해 주어야 사용할 수 있습니다.
ArrayList는 배열처럼 인덱스를 이용하여 할당된 값을 불러올 수 있고, 값을 할당할 수 있으며, 배열과는 달리 배열의 크기를 지정할 필요 없이 값을 추가, 삭제하며 자동으로 배열의 메모리 크기를 늘렸다 줄였다 할 수 있습니다.
또한 ArrayList는 모든 타입의 변수를 담을 수 있다는 장점도 가지고 있습니다.
물론, ArrayList 뿐만 아니라 Collections 에서 제공하는 자료구조는 모든 타입의 변수를 담을 수 있습니다.
모든 타입을 담을 수 있는 이유는 바로 Collections에 속한 요소는 어떤 타입이든지 object 타입으로 저장되기 때문입니다.
7.1 개념
ArrayList은 System.Collections 네임스페이스에 정의된 클래스로, 가변 크기의 배열을 나타냅니다. ArrayList은 객체의 리스트를 관리하며, 배열과 유사하지만 크기가 동적으로 조절될 수 있습니다.
7.2 형식
ArrayList 변수명 = new ArrayList();
using System.Collections;
// ArrayList 선언
ArrayList myArrayList = new ArrayList();
// 초기값을 가진 ArrayList
ArrayList myArrayList = new ArrayList() { 1, "Hello", 3.14, true };
7.3 활용
7.3.1 요소 추가 및 제거
ArrayList myArrayList = new ArrayList();
// 요소 추가
myArrayList.Add(10);
myArrayList.Add("C#");
myArrayList.Add(3.14);
// 요소 제거
myArrayList.Remove("C#");
7.3.2 요소 접근
ArrayList myArrayList = new ArrayList() { 1, "Hello", 3.14, true };
// 인덱스를 사용한 요소 접근
object element = myArrayList[1];
7.4 사용 예
using System;
using System.Collections;
class Program
{
static void Main()
{
// ArrayList 생성
ArrayList myArrayList = new ArrayList();
// 요소 추가 : 정수, 문자열, 실수 등 다양한 타입의 요소를 추가합니다.
myArrayList.Add(10);
myArrayList.Add("C#");
myArrayList.Add(3.14);
// 요소 출력 : foreach 문을 사용하여 ArrayList 에 있는 모든 요소를 출력합니다.
Console.WriteLine("ArrayList 요소:");
foreach (object element in myArrayList)
{
Console.WriteLine(element);
}
// 특정 요소 제거 : Remove 메서드를 사용하여 특정요소를 제거합니다.
myArrayList.Remove("C#");
// 수정된 ArrayList 출력
Console.WriteLine("\nArrayList 수정 후:");
foreach (object element in myArrayList)
{
Console.WriteLine(element);
}
}
}
ArrayList을 사용하여 요소를 추가하고 제거한 후, 결과를 출력하는 프로그램입니다.
이 예제에서는 ArrayList이 여러 데이터 형식을 가진 요소를 저장하고, 요소를 추가하고 제거하여 동적으로 변하는 특징을 보여줍니다. 그러나 주의해야 할 점은 ArrayList이 object 형식을 사용하므로 요소에 접근할 때 형변환을 해야 합니다. 이로 인해 박싱과 언박싱이 발생할 수 있어 성능 저하가 있을 수 있습니다.
최신 C# 버전에서는 이러한 성능 이슈를 개선하기 위해 제네릭 컬렉션 (List<T>)을 사용하는 것이 권장됩니다.
8. ArrayList 요소 삽입과 요소의 제거
ArrayList 클래스에서 Insert, Remove, RemoveAt 메서드는 각각 요소의 삽입, 요소의 제거(값에 의한 제거 및 인덱스에 의한 제거)를 수행합니다.
8.1 Insert 메서드
Insert 메서드는 지정된 위치(index)에 새로운 요소를 삽입합니다. 기존의 요소들은 뒤로 이동하게 됩니다.
ArrayList myArrayList = new ArrayList() { 1, 2, 3, 4, 5 };
// 인덱스 2 위치에 10 삽입
myArrayList.Insert(2, 10);
위의 예제에서는 myArrayList의 인덱스 2 위치에 10을 삽입하였습니다. 결과적으로 배열은 [1, 2, 10, 3, 4, 5]가 됩니다.
8.2 Remove 메서드
Remove 메서드는 지정된 값을 가진 첫 번째 요소를 삭제합니다. 만약 같은 값이 여러 개 존재한다면, 첫 번째로 발견되는 것만 제거됩니다.
ArrayList myArrayList = new ArrayList() { 1, 2, 3, 4, 5 };
// 값 3을 가진 요소 제거
myArrayList.Remove(3);
위의 예제에서는 myArrayList에서 값이 3인 첫 번째 요소를 제거하였습니다. 결과적으로 배열은 [1, 2, 4, 5]가 됩니다.
8.3 RemoveAT 메서드
RemoveAt 메서드는 지정된 인덱스 위치에 있는 요소를 삭제합니다.
ArrayList myArrayList = new ArrayList() { 1, 2, 3, 4, 5 };
// 인덱스 2 위치의 요소 제거
myArrayList.RemoveAt(2);
위의 예제에서는 myArrayList의 인덱스 2 위치에 있는 요소를 제거하였습니다. 결과적으로 배열은 [1, 2, 4, 5]가 됩니다.
Reomve 는 값 매칭 (Value Matching) 이고, RemoveAT은 인덱스 매칭(Index Matching) 입니다.
즉 Remove(argument) 함수는 매개변수로 전달된 값을 찾아서(제일 먼저 찾은 인덱스) 해당 값을 제거하는 것이고, RemoveAT(number)은 매개변수로 전달된 number(인덱스)를 찾아서 해당 값을 제거하는 것입니다.
자료구조와 함께 박싱과 언박싱, 제네릭컬렉션에 대해서는 다음 포스팅에서 알아보겠습니다.
'Programming' 카테고리의 다른 글
예외처리 및 프로그램 디버깅 : 쉽고 재미있는 C# Programming 의 기본 (0) | 2024.01.30 |
---|---|
자료구조 : 쉽고 재미있는 C# Programming 의 기본 (0) | 2024.01.24 |
콜백 메서드 : 쉽고 재미있는 C# Programming 의 기본 (0) | 2024.01.22 |
델리게이트 : 쉽고 재미있는 C# Programming 의 기본 (0) | 2024.01.19 |
추상화 - 추상클래스와 인터페이스 : 쉽고 재미있는 C# Programming 의 기본 (0) | 2024.01.18 |