-
다시한번 개발자도전! 6일차 (배열,컬렉션)다시한번 개발자도전! 2026. 1. 9. 16:26
오늘은 늦잠을 자서 일어나자마자
눈꼽떼고 바로 수업 들었다,,

1.1차원 배열 (Array)
- 연속된 메모리: 데이터가 붙어 있어 인덱스로 즉시 접근 가능함.
- 고정 크기: 한 번 정한 크기는 바꿀 수 없음.
- 동일 타입: 모든 요소의 데이터 타입이 같아야 함.
- 동일한 타입의 데이터를 연속된 메모리 공간에 저장하는 가장 기본적인 자료구조임.
static void Main(string[] args) { //다양한 선언방식 int[] ints = new int[5]; int[] ints2 = new int[] { 0, 1, 2, 3}; int[] ints3 = { 0, 1, 2, 3 }; ints[0] = 0; //인덱스로 접근하여 데이터를 넣어줌 ints[1] = 1; ints[2] = 2; ints[3] = 3; ints[4] = 4; for (int i = 0; i < ints.Length -1; i++) { Console.WriteLine(ints[i]); } }🔥실습🔥
더보기💻 실습: 장비 관리 시스템
- 사용자로부터 입력을 받아 아이템창을 채우는 간단한 로직임.
- 배열은 동일한 타입의 데이터를 연속된 메모리 공간에 저장하는 가장 기본적인 자료구조임.
static void Main(string[] args) { string[] items = new string[5]; int i = 0; while (true) { Console.Write("장비 이름을 입력하세요: "); items[i]=Console.ReadLine(); i++; if (items[items.Length -1] != null) { Console.WriteLine("아이템창이 모두 찼습니다."); break; } } for(int j = 0; j < items.Length ; j++) { Console.WriteLine($"{j+1}번 아이템: {items[j]}"); } }🔥최고점 최저점 찾기
static void Main(string[] args) { int[] scores = { 25, 58, 23, 15 }; int max= scores[0]; int min = scores[0]; for (int i = 1; i < scores.Length; i++) { if (max < scores[i]) max = scores[i]; if (min > scores[i]) min = scores[i]; } }📑 C# 배열(Array) 주요 속성 및 메서드 요약
C#에서 배열을 다룰 때 꼭 알아야 하는 핵심 기능들이니 참고하면 좋음.
구분 속성 및 메서드 설명 속성 Length 배열 요소의 총 개수를 반환함. Rank 배열의 차수(1차원, 2차원 등)를 알려줌. 메서드 Array.Sort(a) a 배열의 요소를 오름차순으로 정렬해줌. Array.Reverse(a) a 배열 요소들의 순서를 반환(뒤집기)함. Array.Clear(a) a 배열의 모든 요소를 초기화(0 또는 null)함. Clone() 현재 배열과 동일한 내용을 가진 배열을 복사함 (얕은 복사). Array.Copy(a, n1, b, n2, len) a 배열의 n1부터 len 길이만큼 b 배열의 n2 위치에 복사함. Array.IndexOF(a,찾는값) 지정한 개체를 검색하여 처음으로 일치하는 인덱스를 반환 CopyTo(b, n) 현재 배열의 모든 요소를 b 배열의 n 인덱스 위치부터 복사함. GetLength(n) n차원의 요소 개수를 리턴함 (n은 0부터 시작). GetValue() 지정한 인덱스 위치의 요소값을 가져옴. SetValue() 지정한 인덱스 위치에 특정 값을 저장함.
2. 다차원 배열 (2D Array)
- 엑셀 시트처럼 **행(Row)과 열(Column)**로 이루어진 표 형태의 자료구조임.
- int[,] 형태로 선언하며, 모든 행의 길이가 같은 직사각형 형태의 배열임.
- 구조: 메모리에 하나의 거대한 블록으로 할당되어 관리됨.
- 용도: 바둑판, 엑셀 시트처럼 격자 구조의 데이터를 다룰 때 유리함.
📊 주요 속성 요약
속성/메서드 설명 비유 GetLength(0) 행(Row)의 길이 세로 줄이 몇 개인가? GetLength(1) 열(Column)의 길이 가로 줄이 몇 개인가? Length 배열의 전체 요소 개수 ($행 \times 열$) 아파트 전체 방 개수 🔥실습🔥
더보기🔥좌석 배치하기
- //[A1][A2][A3]
//[B1][B2][B3]
//[C1][C2][C3]
static void Main(string[] args) { string targetSeat = "A1"; string[,] seats = new string[3, 3] //크기를 미리 정해줌 { { "A1","A2","A3"}, { "B1","B2","B3"}, { "C1","C2","C3"} }; Console.WriteLine("=== 좌석 배치도 ==="); for (int row = 0; row < seats.GetLength(0); row++) { for (int col = 0; col < seats.GetLength(1); col++) { if (seats[col, row] == targetSeat) Console.WriteLine($"({col},{row}\n)"); } } }🔥미니맵 만들기
static void Main(string[] args) { int[,] map = new int[5, 5] { { 0,0,1,0,0}, { 0,2,1,0,3}, { 0,0,1,0,0}, { 1,1,1,0,0}, { 0,0,0,0,9}, }; Console.WriteLine("==던전맵=="); Console.WriteLine("0: 통로 1: 벽 2: 몬스터 3: 보물 9: 출구\n"); Console.OutputEncoding = Encoding.UTF8; for (int y = 0; y < map.GetLength(0); y++) { for (int x = 0; x < map.GetLength(1); x++) { switch (map[y, x]) { case 0: Console.Write("⬜ "); break; case 1: Console.Write("⬛ "); break; case 2: Console.Write("👹 "); break; case 3: Console.Write("💎 "); break; case 9: Console.Write("🚪 "); break; } } Console.WriteLine(); } }🔥성적표 만들기
static void Main(string[] args) { int[,] scores = new int[3, 4] { { 85, 90, 88, 92 }, { 78, 85, 90, 87 }, { 92, 88, 95, 90 } }; string[] students = { "김철수", "이영희", "박민수" }; string[] subjects = { "국어", "영어", "수학", "과학" }; Console.WriteLine("=== 성적표 ===\n"); Console.Write("이름\t"); foreach (string subject in subjects) { Console.Write($"{subject}\t"); } Console.WriteLine("평균"); Console.WriteLine("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); for (int i = 0; i < scores.GetLength(0); i++) { Console.Write($"{students[i]}\t"); int sum = 0; for (int j = 0; j < scores.GetLength(1); j++) { Console.Write($"{scores[i, j]}\t"); sum += scores[i, j]; } double average = (double)sum / scores.GetLength(1); Console.WriteLine($"{average:F1}"); } Console.WriteLine("\n=== 과목별 평균 ==="); for (int subject = 0; subject < scores.GetLength(1); subject++) { int sum = 0; for (int student = 0; student < scores.GetLength(0); student++) { sum += scores[student, subject]; } double avg = (double)sum / scores.GetLength(0); Console.WriteLine($"{subjects[subject]}: {avg:F1}점"); } }
3. 가변 배열 (Jagged Array)
- **'배열의 배열'**이라고도 하며, 각 행마다 길이가 다른 독특한 구조임.
- 특징: 메모리를 필요한 만큼만 효율적으로 쓸 수 있음.
- 주의: Rank를 찍으면 언제나 1이 나옴 (1차원 배열이 겹쳐진 형태라 그럼).
- Length도 전체 칸 수가 아니라, **'행의 개수'**만 알려줌.
📊 다차원 배열 vs 가변 배열 비교
구분 다차원 배열 (int[,]) 가변 배열 (int[][]) 모양 정해진 직사각형 (Matrix) 들쭉날쭉한 모양 (Jagged) 메모리 한 번에 연속된 공간을 차지함 각 배열이 별도의 메모리 주소를 가짐 길이 모든 행의 길이가 같아야 함 행마다 길이를 다르게 줄 수 있음 속도 접근 속도가 미세하게 더 빠를 수 있음 유연성이 높지만 메모리 관리가 조금 더 복잡함 static void Main(string[] args) { string[][] raid = new string[3][]; raid[0] = new string[] { "전사", "힐러", "마법사", "궁수" }; //4명 raid[1] = new string[] { "도적", "전사", "힐러" }; //3명 raid[2] = new string[] { "마법사", "궁수", "힐러", "전사", "탱커" }; //5명 Console.WriteLine("=== 레이드 파티 구성 ==="); for (int i = 0; i < raid.Length; i++) { Console.WriteLine($"파티 {i + 1} ({raid[i].Length}명):"); for (int j = 0; j < raid[i].Length; j++) //각 행의 길이가 다르기 때문에 반드시 raid[i].Length 를 써서 각 줄의 길이를 따로 체크해야 함. { Console.WriteLine($" - {raid[i][j]}"); } } }
4 List<T> (동적 배열)
- 크기가 자동으로 늘어나는 배열.
- Add(): 데이터 추가
- Count: 현재 요소 개수 (배열의 Length와 같음)
static void Main(string[] args) { List<string> inventory = new List<string>(); Console.WriteLine("=== 도적 인벤토리 시스템 =="); //아이템 추가 (Add) inventory.Add("회복 포션"); inventory.Add("마나 포션"); inventory.Add("강철 검"); Console.WriteLine("아이템 3개 추가"); //현재 인벤토리 Console.WriteLine($"인벤토리 ({inventory.Count}개):"); for (int i = 0; i < inventory.Count; i++) { Console.WriteLine($"[{i}] {inventory[i]}"); } Console.WriteLine(); inventory[0] = "초록포션"; for (int i = 0; i < inventory.Count; i++) { Console.WriteLine($"[{i}] {inventory[i]}"); } }
5. 딕셔너리(Dictionary<TKey, TValue>)
- '키'를 통해 '값'을 찾는 사전식 자료구조
- 해시 테이블 기반: 내부적으로 해시 알고리즘을 사용해 데이터를 저장하므로, 양이 아무리 많아도 원하는 데이터를 찾는 속도가 매우 빠름.
- 활용: 아이템 ID로 정보를 찾거나, 닉네임으로 점수를 관리할 때 필수적임.
static void Main(string[] args) { Dictionary<string, int> stats = new Dictionary<string, int>(); //데이터추가 stats.Add("HP", 150); stats.Add("MP", 80); stats.Add("공격력", 75); stats.Add("방어력", 50); stats.Add("민첩", 60); Console.WriteLine("=== 캐릭터 스탯 ==="); foreach (KeyValuePair<string, int> stat in stats) { Console.WriteLine($"{stat.Key}: {stat.Value}"); } //키 존재 확인 string searchStat = "방어력"; if (stats.ContainsKey(searchStat)) { Console.WriteLine(stats[searchStat]); } else { Console.WriteLine("해당스탯이 없습니다."); } }💡딕셔너리에서 쓰기 좋은 foreac란?
더보기- foreach는 배열이나 컬렉션(List, Dictionary 등)의 모든 요소를 하나씩 순차적으로 순회할 때 사용하는 반복문
- 안정성: 인덱스 범위(IndexOutOfRangeException)를 벗어나는 실수를 원천 차단함.
- 읽기 전용(Read-Only): foreach 문 안에서 순회 중인 요소를 직접 수정하려고 하면 에러 남. 데이터를 안전하게 보호할 때 좋음.
foreach (데이터타입 변수명 in 컬렉션이름) { // 실행할 코드 }🔥실습🔥
더보기🔥상점 만들기
static void Main(string[] args) { Dictionary<string, int> items = new Dictionary<string, int>(); int gold = 600; items.Add("회복 포션", 150); items.Add("마나 포션", 40); items.Add("강철 검", 500); items.Add("가죽 갑옷", 300); items.Add("마법 반지", 1000); Console.WriteLine("=== 상점 아이템 ==="); foreach (KeyValuePair<string, int> tems in items) { Console.WriteLine($"{tems.Key} : {tems.Value} 골드"); } Console.WriteLine(); Console.Write("구매할 아이템을 입력하세요: "); string itemname = Console.ReadLine(); if if (items.ContainsKey(itemname) && gold >= items[itemname]) { gold -= items[itemname]; Console.WriteLine($"{itemname} 구매완료!"); Console.WriteLine($"남은 골드: {gold} 골드"); } else Console.WriteLine("구매실패"); }컬렉션에 대한 자세한 것들은 따로 글을 빼서 만들어야 겠다.

'다시한번 개발자도전!' 카테고리의 다른 글
c# 컬렉션(Collection)/List,Dictionary,Stack,Queue (3) 2026.01.12 다시한번 개발자도전! 7일차 (함수,재귀함수,메모리구조,ref,out) (0) 2026.01.12 다시한번 개발자도전! 5일차 (이중반복문 , 콘솔 좌표이동) (0) 2026.01.08 다시한번 개발자도전! 4일차(삼항연산자,연산자 우선순위,제어문,반복문) (0) 2026.01.07 다시한번 개발자도전! 3일차 (외부입력받기,연산자,형변환) (0) 2026.01.06