컬렉션
- 이름 하나로 데이터 여러개를 담을 수 있는 그릇
- C# 컬렉션 - 배열(array) 리스트(list), 사전(dictionary)등등
배열
var array = new string[] {"Array", "List", "Dictionary"};
foreach (var arr in array) {Console.WriteLine(arr);}
- 출력값
Array
List
Dictionary
리스트
var list = new List<string> {"Array", "List", "Dictionary"};
foreach (var item in list ) {Console.WriteLine(item );}
- 출력값
Array
List
Dictionary
사전(Dictionary)
var dictionary= new Dictionary<int, string>{{0,"Array"}, [1,"List"}, {2, "Dictionary"}};
foreach (var pair in dictionary) {Console.WriteLine($"{pair.Key} - {pair.Value}"); }
- 출력값
0 - Array
1 - List
2 - Dictionary
- 배열 이름 하나에 데이터 여러개를 보관.
- 각 요소는 인덱스로 접근 가능하며, 인덱스는 0부터 시작.
- 메모리의 연속된 공간을 할당하고, 대괄호([])와 0 부터 시작하는 정수형 인덱스를 사용ㅎ가며 접근.
- new 키워드로 배열을 생성한 이후로 사용.
int [] numbers;
numbers = new int[3];
int[] intArray = new int[3];
배열의 종류
- 1차원 배열 :배열의 첨자를 하나만 사용하는 배열
- 다차원 배열 : 첨자 2개 이상을 사용하는 배열(2차원, 3차원)
- 가변(jagged)배열 : 배열의 배열, 이름 하나로 다양한 차원의 배열을 표현.
int[] intArray; // 일차원 배열 선언
intArray = new int[3]; // 메모리 영역 확보(0, 1, 2)
intArray[0] = 1; // 배열 초기화
intArray[1] = 2;
intArray[2] = 3;
// 배열 선언, 요소 생성, 초기화를 동시에...
int[] intArray = new int[3] { 1, 2, 3 };
// 요소 수 생략 가능 (지정한 요소의 수만큼 자동 생성)
var intArray = new int[] { 1, 2, 3 };
// new 키워드와 int[] 생략하고 바로 초기화 가능
int[] intArray = { 1, 2, 3 };
//foreach로 순회
class ArrayForEach
{
static void Main()
{
// float 형식의 데이터를 3개 저장하는 1차원 배열 arr 생성
float[] arr = { 10.5f, 20.1f, 30.2f };
float sum = 0.0f; // 배열의 합을 저장해 놓을 sum 변수 선언과 동시에 0으로 초기화
foreach (float f in arr) // arr 변수에 데이터가 있는 동안 반복해서 실행
{
sum += f; // 각각의 요소를 sum 변수에 누적
}
Console.WriteLine(sum); // 60.8
}
}
다차원 배열
class ArrayTwoFor {
static void Main() {
int[,] arr = { { 1, 2, 3 }, { 4, 5, 6 } }; // 이차원 배열 선언/초기화
for (int i = 0; i < 2; i++) // 이중 for 문으로 이차원 배열 출력
{
for (int j = 0; j < 3; j++)
{
Console.WriteLine($"arr[{i},{j}] = {arr[i, j]}");
}
}
}
}
배열의 속성
- Length 속성 : 배열의 길이를 알 수 있음
- Rank 속성 : 배열의 차수를 알 수 있음.(3차원 배열이면 3을 반환)
- GetLength(n) : 각 차수에 해당하는 길이를 알 수 있음.
static void Main() {
// 3차원 배열 선언/요소수생성/초기화: 층/행/열
int[,,] arr = new int[2, 2, 2]
{ { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };
Console.WriteLine("차수 출력: {0}", arr.Rank); // 차수 출력
Console.WriteLine("길이 출력: {0}", arr.Length); // 길이 출력
// 층(면), 행, 열 구분해서 출력
for (int i = 0; i < arr.GetLength(0); i++) {//층
for (int j = 0; j < arr.GetLength(1); j++) {//행
for (int k = 0; k < arr.GetLength(2); k++) {//열
Console.Write("{0}\\t", arr[i, j, k]);
}
Console.WriteLine(); //줄바꿈
}
Console.WriteLine(); //줄바꿈
}
}
가변 배열
- 배열 길이가 가변 길이인 배열
static void Main()
{
// 배열 생성 시 [2][] 형태로 2번째를 비워두면 동적으로 초기화 가능
int[][] zagArray = new int[2][];
zagArray[0] = new int[] { 1, 2 }; // 0번째 행에 2개의 요소로 초기화
zagArray[1] = new int[] { 3, 4, 5 }; // 1번째 행에 3개의 요소로 초기화
for (int i = 0; i < 2; i++)
{
// n번째 행의 길이만큼 반복: 2번, 3번 반복
for (int j = 0; j < zagArray[i].Length; j++)
{
Console.Write($"{zagArray[i][j]}\\t");
}
Console.WriteLine();
}
}
var 키워드로 배열 선언
- 배열도 이름 앞에 var 키워드 사용가능.
class ArrayWithVarKeyword {
static void Main() {
//변수 선언 시 var 키워드를 사용한 후 입력 값의 형식을 GetType() 메서드로 출력 예시
var i = 5; // int i = 5; // 정수 형식으로 자동적으로 형식이 설정됨
Console.WriteLine("i : {0}, 타입 : {1}", i, i.GetType());
var s = "Hello"; // 문자열 형식으로 형식화됨
Console.WriteLine("s : {0}, 타입 : {1}", s, s.GetType());
// 배열 형식
var numbers = new int[] { 1, 2, 3 };
foreach (var item in numbers) {// var item에서 item은 numbers 형식
Console.WriteLine("item : {0}, 타입 : {1}", item, item.GetType());
}
}
}
함수
- 반복하여 사용하도록 이름 하나로 만들어 놓은 코드의 집합
- C#에서는 함수보다는 메서드로 표현
- 어떤 값을 받아서 가공을 하여 결과값을 반환시키는 코드
- 프로그램 내에서 특정한 기능을 처리하는 독립적인 하나의 단위 또는 모듈
- 함수와 메서드를 루틴으로 표현하기도 함.
- 서브 프로시저, 서부루틴
메서드
- 객체지향 프로그래밍에서 객체와 관련된 서브 루틴(또는 함수)이자 클래스가 가지고 있는 기능.
- 데이터와 멤버변수에 대한 접근 권한을 갖는다.
내장함수
- C#이 자주 사용하는 기능을 미리 만들어서 제공.
- 문자열 관련, 날짜 및 시간 관련, 수학 관련, 형식 변환 관련등등
- API임.
사용자 정의 함수
- 프로그래머 필요할 때마다 새롭게 기능을 추가하여 사용.
매개변수(인자, 파라미터)
- 함수에 어떤 정보를 넘겨주는 데이터
- 함수를 호출 할때마다 매개변수를 달리하여 함수의 기능이 달라지게 할 수 있음.
- 콤마(,)를 기준으로 여러개 설정가능.
- 문자열과 숫자등 모든 데이터 형식을 사용가능.
즉, 함수 오버로딩이 가능.
매서드 시그니처(signature)
public static void Main(string[] args)
{
}
- public
- 액세스 한정자
- public : 모든 클래스에서 사용가능.
- private : 현재 속해있는 클래스에서만 사용가능.
- static : 정적인 메서드(안붙을 시 인스턴스 메서드)
- void : 반환값 없음.
- Main() : 메서드 이름
- String[] args : 매개변수(배열)
기본 매개 변수
- 메서드를 선언 할 시 매개변수를 선언과 동시에 초기화 하는 것.
- 메서드 호출 시 매개변수를 지정하지 않아도 자동값으로 자동 설정
- default parameter 또는 선택적 인수(optional argument)라고 함.
static void Log(string message, byte level = 1)
{
console.WriteLine($"{message}, {level}");
}
명명된 매개변수
- 함수 호출시 필요한 매개변수 이름을 직접 지정(순서 무관)
static void Main() {
Sum(10, 20);
Sum(first: 10, second: 20); // named parameter
Sum(second: 20, first: 10); // named parameter
}
static void Sum(int first, int second) {
Console.WriteLine(first + second);
}
함수 오버로드
- 하나의 클래스에 이름이 동일한 함수 여러개를 매개 변수를 달리해서 정의
class MethodOverloadNumber
{
static void GetNumber(int number) {
Console.WriteLine($"Int32: {number}");
}
static void GetNumber(long number) {
Console.WriteLine($"Int64: {number}");
}
static void Main() {
GetNumber(1234); // Int32: 1234
GetNumber(1234L); // Int64: 1234
}
}
재귀 함수
- 함수 내에서 함수 자신을 호출
- 재귀호출은 스택 메모리에 저장되는 형태로 실행
- 너무 많은 재귀 처리는 스택 오버플로우 에러 발생 가능
- 많은 양의 데이터를 처리하는 코드에서는 재귀호출 보다는 반복문을 사용하길 권장.
using System;
class RecursionDemo
{
static void Main()
{
// 재귀 호출을 사용하여 Factorial을 구하기: 4! = 4 * 3 * 2 * 1 = 24
Console.WriteLine(4 * 3 * 2 * 1); // 24
Console.WriteLine(FactorialFor(4)); // for문을 이용 (재귀X)
Console.WriteLine(Factorial(4)); // if문을 이용 (재귀)
Console.WriteLine(Fact(4)); // 3항 연산자를 사용 (재귀)
}
// 반복문을 이용한 팩토리얼
static int FactorialFor(int n)
{
int result = 1;
for (int i = 2; i <= n; i++)
{
result *= i;
}
return result;
}
// if문을 사용한 재귀 팩토리얼
static int Factorial(int n)
{
if (n <= 1)
return 1;
else
return n * Factorial(n - 1);
}
// 3항 연산자를 사용한 재귀 팩토리얼
static int Fact(int n) => (n <= 1) ? 1 : n * Fact(n - 1);
}
화살표 함수
- 화살표 연산자(⇒)를 사용.
- 람다식의 또다른 이름.
- 화살표 함수를 사용시 함수를 줄여서 표현 가능.
- 함수 고유의 표현을 줄여서 사용하므로, 처음에는 어색.
- 익숙해지면 코드를 간결하게 작성 가능.
class ArrowFunction
{
static void Main()
{
Hi(); // 안녕하세요.
Multiply(3, 5); // 15
}
static void Hi() => Console.WriteLine("안녕하세요.");
static void Multiply(int a, int b) => Console.WriteLine(a * b);
}
class ExpressionBodiedMethod
{
static void Main()
{
//[!] 아래에 함수를 먼저 만들고 호출해야 함
Log("함수 축약");
Console.WriteLine(IsSame("A", "B")); // False
}
static void Log(string message) => Console.WriteLine(message);
static bool IsSame(string a, string b) => a == b;
}
델리게이트
- 대리자라고도 불림.
- 메서드를 변수처럼 저장하고 호출하는 방법
- delegate 키워드를 사용하여 만듬.
- 함수 자체를 하나의 데이터로 보고 의미 그대로(대리자) 다른 메서드를 대신 실행하는 기능.
- 한 번에 하나 이상의 메서드를 대신해서 호출할 수 있는 개념.
- 메서드의 매개변수로 대리자 변수9개체)를 넘길 수 있음.
- 대리자를 사용하여 함수의 매개변수로 함수자체를 전달 가능.
- 대리자는 동일한 메서드 시그니처를 갖는 메서드 참조를 담을 수 있는 그릇 역할을 함.
class DelegateDemo
{
delegate void PrintMessage(string message);
static void SayHi(string msg) {
Console.WriteLine("Hi: " + msg);
}
static void Main() {
PrintMessage pm = SayHi;
pm("Everyone"); // 출력 Hi: Everyone;
}
}
- 대리자를 생성 했다면 해당 대리자를 사용하여 구조가 동일한 다른 메서드를 대신 호출 가능.
- 대리자 형식 변수에 메서드를 등록하는 코드
대리자 변수 = new 대리자(메서드이름);
- += 연산자를 이용해 대신할 메서드를 하나 이상 등록 가능.
대리자 변수 += new 대리자(메서드 이름);
델리게이트로 메서드 호출
class DelegateNote
{
delegate void SayPointer(); // 대리자
static void Hello() => Console.WriteLine("Hello Delegate"); // 샘플 함수
static void Main()
{
SayPointer sayPointer = new SayPointer(Hello); // 대리자의 인스턴스 생성
sayPointer(); // a, 대리자 인스턴스에 괄호를 붙여 메서드 호출
sayPointer.Invoke(); // b, 명시적으로 Invoke() 메서드 호출
}
}
- 매개변수와 반환값이 있는 메서드
class DelegateGetArea
{
static double GetArea(int r) => 3.14 * r * r;
delegate double GetAreaPointer(int r);
static void Main()
{
GetAreaPointer pointer = GetArea;
Console.WriteLine(pointer.Invoke(10));
Console.WriteLine(pointer(10));
}
}
델리게이트 / 람다
- 람다식은 델리게이트를 구현하는 방법 중 하나.
- 델리게이트 →메서드 참조를 저장하는 틀(frame)
- 람다식 → 틀에 들어갈 내용을 간결히 작성하는 도구.
- (CLR 관점에서 람다식은 컴파일러에 의해서 델리게이트로 변환 되어서 실행됨)
- 여러 메서드를 연결(멀티캐스트)하거나, 명시적 메서드 참조가 필요한 경우 : 델리게이트
- 간단한 로직을 즉시 정의하거나, LINQ 쿼리처럼 짧은 콜백이 필요할 시 : 람다
- 델리게이트와 람다를 함께 사용하면 유연성이 극대화됨.
델리게이트로 메서드 호출
- 익명 메서드 호출
class AnonymousDelegate
{
delegate void SayDelegate();
static void Main()
{
// delegate 키워드로 함수를 바로 정의해서 사용
SayDelegate say = delegate ()
{
Console.WriteLine("반갑습니다.");
};
say();
}
}
- 메서드 매개 변수로 대리자를 넘겨줌
반응형
'Game DevTip > C#' 카테고리의 다른 글
4. C# 인터페이스 및 추상클래스 ,다형성 (0) | 2025.04.21 |
---|---|
3. C# 클래스 (0) | 2025.04.21 |
1. C# 기초 (0) | 2025.04.21 |
댓글