Out / ref (modifier)
C#에서 기본 데이터 형식 매개변수는 call by value, value로 값 전달이 기본이다.
이를 reference 형식으로 바꾸고 싶다면 ref / out 키워드를 사용한다.
value와 reference의 차이를 예시를 들어 설명하자면
static void example(int a){
a = 3;
}
위의 코드는 기존의 존재한 int a를 받아 3으로 바꾸는 코드이다.
하지만 void로 설정되어있어 이를 return으로 받지 않는 한 C#은 value형식이기 때문에 a는 3으로 바뀐걸 전달해주지 못한다.
만일 return을 쓰지 않고도 값을 바꾸고 싶다면 reference 형식으로 바꿔야 한다.
static void example1(ref int a){
a = 3;
}
위의 식에 ref라는 키워드를 붙여줌으로써 a는 불려와서 3으로 값이 바뀔 수 있게 되었다.
공통점: 참조를 통해 인수를 전달한다.
이렇게 참조형식으로 가능하게 하는 키워드로 ref 와 out이 있는데 무슨 차이일까?
바로 초기화에 차이점이 존재한다.
ref: 변수를 전달하기 전에 초기화를 해야한다. (주로 기존 변수를 메서드에서 수정할 때 사용)
out: 초기화 할 필요가 없고, 이전의 값은 무시된다. + out은 메서드를 진행하는 동안에 할당되어야 한다. (주로 메서드 내에서 생성된 값을 반환할 때 사용)
매개변수 사용하려면 method 정의와 호출 method가 모두 명시적으로 ref / out 키워드를 사용해야 한다.
한 함수에서 여러 번 ref와 out을 사용할 수 있다.
우리는 위의 상황이나 주로 여러 상황에서 ref를 주로 사용할 것이다.
Stack / Queue
스택과 큐 모두 줄세우기 / 배열과 비슷한 개념이지만, 모두 안쪽의 인덱스에는 직접 접근할 수 없다.
Stack은 동전을 쌓아 먼저 쌓은 동전이 제일 마지막에 뺄 수 있는 개념과 비슷하고, Queue는 줄을 서서 먼저 줄 선 사람은 먼저 들어갈 수 있는 개념과 비슷하다.
Stack : 후입선출, list / array같이 인덱스에 접근할 수 없다 (나가는 애들이 정해져있다)
ex) Ctrl + Z, 동전쌓기
Queue : 선입선출
ex) 대기번호
class Index
{
public int Number { get; set; }
public Index (int number)
{
Number = number;
}
}
시작하기 전, Index 클래스를 선언해 number를 받으면 이를 Number에 저장하게 선언해두었다.
static void first()
{
Stack<Index> stack = new Stack<Index>();
for (int i = 0; i < 5; i++)
{
stack.Push(new Index(i));
}
int stack_count = stack.Count;
for (int i = 0; i < stack_count; i++)
{
Index index = stack.Pop();
Console.WriteLine(index.Number);
}
//4 3 2 1 0
first라는 메소드에 stack 초기화 및 0~4까지 push를 해두었다.
이를 다시 pop해서 뺀 다음 출력한다면 넣은 순서의 반대로 나오는 것을 확인할 수 있다.
스택 선언
Stack<자료형> 스택이름 = new Stack<자료형>();
stack에 추가 및 삭제
스택이름.Push(넣을 내용);
스택이름.Pop(); -> 가장 마지막에 넣은 내용이 나온다.
Queue<Index> queue = new Queue<Index>();
for (int i = 0; i < 5; i++)
{
queue.Enqueue(new Index(i));
}
int queue_count = queue.Count;
for (int i = 0; i < queue_count; i++)
{
Index index = queue.Dequeue();
Console.WriteLine(index.Number);
}
// 0 1 2 3 4 queue[index] 접근이
queue_count = queue.Count;
stack_count = stack.Count;
Console.WriteLine("{0}, {1}", queue_count, stack_count); //0, 0찍힌다 다 꺼낸 후 queue_count는 0
}
큐 선언
Queue<자료형> 큐이름 = new Queue<자료형>();
큐에 추가 및 삭제
큐이름.Enqueue(내용);
큐이름.Dequeue(); -> 선입선출로 반환된다
Hashtable / Dictionary
Hashtable과 Dictionary는 두가지 값을 묶어서 저장하고 접근하는 형태이다.
value를 저장하며 이를 key로 접근하는 형태이다.
index로 접근하는 배열과 리스트와는 다른 형태이다.
Hashtable : type 정하지 않고 사용한다 (object 형태를 사용해 → 박싱 언박싱이 일어나 많이 사용하면 느려진다는 단점이 있다) 주로 자료형을 모를 때나 key값이 중복이 되는 경우에 사용한다
Dictionary : type 정하고 사용하며, key값이 중복이 되면 안된다. key값이 없을 때 빈값을 넣고, 오류를 던진다 (생성 자체가 안 됨)
두가지를 코드에 사용하려면 using문을 추가해야 한다.
using System.Collections;
Hashtable hash = new Hashtable();
hash.Add("a", "apple");
hash.Add("b", "banana");
hash.Add("c", "cat");
for (int i = 0; i < hash.Count; i++)
{
Console.WriteLine((string)hash[i]);
}
Console.WriteLine((string)hash["b"]);
hash.Add(0, "ㅋㅋ");
Console.WriteLine(hash[0]); //-> index 접근이 아닌 key값 0으로 접근한 것임
hashtable에서 key값에 없는 값을 넣으면 빈칸이 출력된다. -> 자료형이 정해져있지 않은 object 형식이기 때문에 (for문의 결과로 빈칸만 나온다)
string hash["b"]의 결과로 banana가 출력되며, key를 0을 가지는 value를 추가해 접근하면 이는 index로 접근하는것 처럼 보일 수 있으나, key값으로 접근한 것을 잊지말자
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(1, "일");
dictionary.Add(2, "이");
dictionary.Add(3, "삼");
for (int i = 0; i < dictionary.Count; i++)
{
Console.WriteLine(dictionary[i+1]);
}
//Console.WriteLine(dictionary[6]); -> dictionary는 object로 받지 않아 키가 없으면 출력 안함
hashtable과 다르게 key에 없는 값을 출력하려고 하면 오류가 나며 코드가 종료된다.
선언할 때 int, string으로 key와 value의 타입을 지정한 부분을 기억해야 한다.
'공부 > C#' 카테고리의 다른 글
[C#] Window 콘솔에서 mp3파일 가져와서 재생하기 (0) | 2023.03.30 |
---|---|
[C#] 디자인패턴 - 싱글톤, Factory, state(상태 패턴) (0) | 2023.03.28 |
[C#] 예외처리 try-catch의 이용과 자료구조 Array, List, ArrayList 차이 (1) | 2023.03.24 |
[C#] 상속과 virtual, abstract, interface / 오버로딩, 오버라이딩 코드 (0) | 2023.03.23 |
[C#] class 추가와 public / private 속성(프로퍼티)의 get set 초기화식 (0) | 2023.03.22 |