|
이번에는 C# 기본 문법을 정리해보도록 하겠습니다.
|
|
# 1. 기본 자료형
|
|
|
|
자료형은 프로그램에서 데이터를 담을 수 있는 일정한 형식을 말하며, 기본 자료형(Primitive Data Type)은 개발자가 별도로 코드를 만들지 않아도 C#언어에서 자체적으로 제공하는 데이터 형식을 의미한다.
|
|
기본 자료형
|
|
|
|
var
|
|
# 2. var
|
|
nullable,
|
|
C# 3.0 컴파일러부터는 타입 추론(Type Inference) 기능이 추가되면서 메서드의 지역 변수 선언을 타입에 관계없이 `var` 예약어로 쓸 수 있게 됐다.
|
|
구조체,
|
|
|
|
stack vs. heap
|
|
`var`를 사용하면 초기화시 변수의 타입이 결정되고 변경할 수 없다.
|
|
value type vs. reference type
|
|
|
|
제어문
|
|
자주 사용하게 되면 코드 가독성이 낮아지지만, 익명 타입(Anonymous Type)이나 제네릭(generic)과 같이 사용하는 경우에 간결한 코드를 작성할 수 있다.
|
|
연산자 |
|
|
|
|
|
```csharp
|
|
|
|
var i = 5 // int type
|
|
|
|
var s = "text" // string type
|
|
|
|
|
|
|
|
List<int> numbers = new List<int>(new int[] { 1,2,3,4,5 });
|
|
|
|
foreach (var elem in numbers)
|
|
|
|
{
|
|
|
|
Console.WriteLine("{0},", elem);
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# 3. nullable
|
|
|
|
C#은 자료형의 형식을 값 형식(Value Type)과 참조 형식(Reference Type)으로 나눌 수 있는데, 참조 형식은 초기값이 null로 표기된다.
|
|
|
|
하지만 값 형식은 초기값이 지정되지 않아서 0 또는 -1과 같은 값으로 초기화하는데, 이는 실제 null과 같이 '어떤 값이 할당되지 않은 상태'가 아니다.
|
|
|
|
이러한 문제를 해결하기위해 값 형식에도 null을 할당할 수 있도록 nullable 형식을 추가하였다.
|
|
|
|
|
|
|
|
|
|
|
|
nullable 형식은 `Nullable<T>` 로 사용할 수 있고, 축약 표기로 `?` 문자를 함께 붙이는 표현도 지원한다.
|
|
|
|
`Nullable<T>`은 HasValue, Value라는 두 가지 속성을 제공하는데, 값이 할당됐는지 여부를 HasValue 불린 값으로 반환하고,
|
|
|
|
값이 있다면 T 타입에 해당하는 값을 Value 속성으로 반환한다.
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
Nullbable<bool> bMarried;
|
|
|
|
bool? bMarried;
|
|
|
|
```
|
|
|
|
# 4. 구조체
|
|
|
|
C#에서는 값 형식의 사용자 정의 형식 표현을 위해 `struct` 예약어를 제공한다.
|
|
|
|
`struct`를 이용하여 정의한 구조체의 특징은 다음과 같다.
|
|
|
|
|
|
|
|
- 인스턴스 생성을 new로 해도 되고, 안 해도 된다.
|
|
|
|
- 기본 생성자는 명시적으로 정의할 수 없다.
|
|
|
|
- 매개변수를 갖는 생성자를 정의해도 기본 생성자가 C# 컴파일러에 의해 자동으로 포함된다.
|
|
|
|
- 매개변수를 받는 생성자의 경우, 반드시 해당 코드 내에서 구조체의 모든 필드에 값을 할당해야 한다.
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
struct Vector
|
|
|
|
{
|
|
|
|
public int X;
|
|
|
|
public int Y;
|
|
|
|
|
|
|
|
public Vector(int x, int y)
|
|
|
|
{
|
|
|
|
this.X = x;
|
|
|
|
this.Y = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
__깊은 복사/얕은복사__
|
|
|
|
- 깊은 복사 : 인스턴스가 가진 메모리 자체가 복사되어 새로운 변수에 대입되는 것. 가리키는 메모리 주소가 다름.
|
|
|
|
- 얕은 복사 : 인스턴스가 가진 메모리를 새로운 변수가 참조하도록 하는 것. 가리키는 메모리 주소가 같음.
|
|
|
|
|
|
|
|
|
|
|
|
__구조체와 클래스를 선택하는 기준__
|
|
|
|
- 일반적으로 모든 사용자 정의 타입은 클래스로 구현한다.
|
|
|
|
- 깊은/얕은 복사의 차이가 민감한 타입은 선택적으로 구조체로 구현한다.
|
|
|
|
- 참조 형식은 GC에 의해 관리받게 된다. GC에 부하를 피해야 하는 경우 구조체를 선택한다.
|
|
|
|
|
|
|
|
# 5. stack vs. heap
|
|
|
|
***스택(stack)***은 1MB의 용량으로 스레드가 생성될 때 스레드마다 할당된다.
|
|
|
|
|
|
|
|
이 공간을 활용해서 메서드의 실행, 해당 메서드로 전달하는 인자, 메서드 내에서 사용되는 지역 변수를 처리한다.
|
|
|
|
|
|
|
|
- 스택 오버플로우(Stack overflow) : 스택에 할당된 용량을 초과하는 메모리 할당이 이루어지는 경우에 발생.
|
|
|
|
|
|
|
|
***힙(heap)***의 경우 CLR에서는 관리 힙(managed heap)을 가리킨다.
|
|
|
|
|
|
|
|
관리 힙이란 CLR의 GC가 할당/해제를 관리하기 때문에 붙여진 이름이다.
|
|
|
|
|
|
|
|
new로 할당되는 모든 참조형 객체는 힙에 할당된다.
|
|
|
|
|
|
|
|
할당된 메모리는 GC에 의해 자동으로 해제된다.
|
|
|
|
|
|
|
|
|
|
|
|
# 6. value type vs. reference type
|
|
|
|
|
|
|
|
***값 형식(value type)***은 메모리에 값을 직접 저장하는 형식이다.
|
|
|
|
|
|
|
|
스택에 할당되며, 메서드 호출 시 값 타입으로 전달되고, 해당 선언 범위(Scope)를 벗어나면 메모리가 해제된다
|
|
|
|
|
|
|
|
기본 데이터 타입(primitive data type), 구조체(struct), 열거형(enumeration) 등이 있다.
|
|
|
|
|
|
|
|
***참조 형식(reference type)***은 메모리에 데이터가 위치한 주소를 저장하는 형식이다.
|
|
|
|
|
|
|
|
힙에 할당되며, 메서드 호출 시 참조 타입으로 전달되고, 가비지 컬렉터에 의해서 메모리가 해제된다.
|
|
|
|
|
|
|
|
클래스(class), 배열(array), 델리게이트(delegate), 인터페이스(interface) 등이 있다.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 7. 제어문
|
|
|
|
|
|
|
|
- 선택문(selection statement) : if, switch
|
|
|
|
- 반복문(iteration statement) : for, foreach, while, do/while
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
// if
|
|
|
|
bool condition = true;
|
|
|
|
if (condition)
|
|
|
|
{
|
|
|
|
Console.WriteLine("The variable is set to true.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Console.WriteLine("The variable is set to false.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// switch
|
|
|
|
int caseSwitch = 1;
|
|
|
|
switch (caseSwitch)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
Console.WriteLine("Case 1");
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
Console.WriteLine("Case 2");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Console.WriteLine("Default case");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// for
|
|
|
|
for (int i = 1; i <= 5; i++)
|
|
|
|
{
|
|
|
|
Console.WriteLin
|
|
|
|
}
|
|
|
|
|
|
|
|
// foreach
|
|
|
|
int[] fibarray = new int[] { 0, 1, 1, 2, 3, 5, 8, 13 };
|
|
|
|
foreach (int element in fibarray)
|
|
|
|
{
|
|
|
|
System.Console.WriteLine(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
// while
|
|
|
|
while (n < 6)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Current value of n is {0}", n);
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// do/while
|
|
|
|
int x = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Console.WriteLine(x);
|
|
|
|
x++;
|
|
|
|
} while (x < 5);
|
|
|
|
```
|
|
|
|
|
|
|
|
# 8. 연산자
|
|
|
|
|
|
|
|
 |
|
|
|
\ No newline at end of file |