[C#] 공용 형식 시스템.
C#은 다양한 종류의 데이터를 다룰수 있다.
byte, int, float, string, object와 같은 다양한 기본데이터 형식을 제공하며,
프로그래머가 이들을 조합해여 복잡한 데이터 형식을 만들어 사용할 수 있다.
또한, C#에서는 스택과 힙이라는 두 가지 메모리 영역을 활용함으로써 변수의 생명주기에 따라 변수를
값 형식이나 참조형식으로 만들어 사용할 수 있다.
이 모든 데이터 형식 체계는 사실 C#의 고유의 것이 아니다.
공용 형식 시스템(Common Type System)이라고 하는 .NET 프레임워크의 형식 체계의 표준을 그대로
따르고 있을 뿐이다.
공용 형식 시스템의 뜻을 풀어보자면 "모두가 함께 사용하는 데이터 형식 체계" 라고 할 수 있다.
C#을 비롯한 .NET 프레임워크를 지원하는 모든언어를 뜻한다.
마이크로소프트가 이러한 시스템을 도입한 이유는 .NET 언어들끼리 호환성을 갖도록 하기 위해서이다.
C#과 C++의 기본 데이터 형식을 살펴 보도록 하자.
클래스 이름 |
C# 형식 |
C++ 형식 |
비주얼 베이직 형식 |
System.Byte |
byte |
unsigned char |
Byte |
System.SByte |
sbyte |
char |
SByte |
System.Int16 |
short |
short |
Short |
System.Int32 |
int |
int 또는 long |
Integer |
System.Int64 |
long |
__int64 |
Long |
System.UInt16 |
ushort |
unsigned short |
UShort |
System.UInt32 |
uint |
unsigned int 또는 unsigned long |
UInteger |
System.UInt64 |
ulong |
unsigned __int64 |
ULong |
System.Single |
float |
float |
Single |
System.Double | double | double | Double |
System.Boolean | bool | bool | Boolean |
System.Char | char | wchar_t | Char |
System..Decimal | decimal | Decimal | Decimal |
System.IntPtr | 없음 | 없음 | 없음 |
System.UIntPtr | 없음 | 없음 | 없음 |
System.Object | object | Object* | Object |
System..String | string | String* | String |
공용 형식 시스템의 형식은 각 언어에서 코드에 그대로 사용할수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | using System; namespace CTS { class MainApp { static void Main(string[] args) { System.Int32 a = 123; int b = 456; Console.WriteLine("a type:{0}, value:{1}", a.GetType().ToString(), a); Console.WriteLine("b type:{0}, value:{1}", b.GetType().ToString(), b); System.String c = "abc"; string d = "def"; Console.WriteLine("c type:{0}, value:{1}", c.GetType().ToString(), c); Console.WriteLine("d type:{0}, value:{1}", d.GetType().ToString(), d); // 결과 // a type: System.Int32, value: 123 // b type: System.Int32, value: 456 // c type: System.String, value: abc // d type: System.String, value: def } } } | cs |
※ GetType() 메소드 ToString() 메소드
모든 데이터 형식은 object 형식으로부터 상속받는다고 말한적이 있을것이다.
GetType()와 ToString()메소드는
System.Int32와 int, System.String과 string 형식이
object형식으로부터 물려받아 갖고 있는 것이다.
'C#' 카테고리의 다른 글
[C#] 메소드 오버로딩, 가변길이 매개 변수, 선택적 매개 변수 (0) | 2017.03.25 |
---|---|
[C#] 참조에 의한 매개 변수 전달. ref / 출력 전용 매개 변수. out (0) | 2017.03.24 |
[C#] var형식 (0) | 2017.03.24 |
[C#] Object형식, 박싱과 언박싱. (1) | 2017.03.23 |
[C#] 값 형식과 참조형식 (0) | 2017.03.23 |
[C#] var형식
C#은 변수나 상수에대해 깐깐하게 형식 검사를 하는 강력한 형식의 언어이다.
하지만, 약한 형식 검사를 지원해주기도 한다. 바로 var라는 키워드 이다.
강력한 형식검사
- 강력한 형식 검사는 프로그래머의 실수를 줄여주는 장점이 있다.
- 의도치 않은 형식의 데이터를 읽거나 할당하는 일을 막아준다.
약한 형식검사(var)
- 자동으로 해당 변수의 형식을 지정해준다.
- int, long, unit, ulong 같은 형식을 외울 필요가 없다.
- 변수의 선언과 동시에 초기화 해야한다.
- 지역 변수로만 사용할 수 있다.
var키워드를 사용해 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; namespace UsingVar { class MainApp { static void Main(string[] args) { var a = 20; Console.WriteLine("Type {0}, Value {1}", a.GetType(), a); // 결과 : Type: System.Int32, Value: 20 var b = 3.14; Console.WriteLine("Type {0}, Value {1}", b.GetType(), b); // 결과 : Type: System.Double, Value: 3.14 var c = "헬로우 월드?"; Console.WriteLine("Type {0}, Value {1}", c.GetType(), c); // 결과 : Type: System.String, Value: 헬로우 월드? } } } | cs |
배열도 사용 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System; namespace UsingVar { class MainApp { static void Main(string[] args) { var a = new int[] {10,20,30}; Console.WriteLine("Type {0}, Value: ", a.GetType()); foreach(var e in a) Console.Write("{0} ", e) Console.WriteLine(); // 결과 : Type: System.Int32[], Value: 10 20 30 } } } | cs |
※ var형식과 object형식
위의 예제코드를 object형식으로도 작성이 가능하다.
그럼 var와 object는 같은거 아닌가? 라고 생각할수도 있지만.
아니다.
object a = 20;
이라는 코드가 있다고 하자.
컴파일이 실행되면 20은 박싱되어 힙에 들어가고 a는 힙을 가르키게 된다.
var a = 20;은 컴파일러가 a의 형식을 파악한다.
int a = 20;으로 바꿔 컴파일 시킨다.
컴파일이 실행되면 a를 스택에 올려놓게 된다.
두 개의 형식은 명확히 다른거라고 알아두자.
'C#' 카테고리의 다른 글
[C#] 메소드 오버로딩, 가변길이 매개 변수, 선택적 매개 변수 (0) | 2017.03.25 |
---|---|
[C#] 참조에 의한 매개 변수 전달. ref / 출력 전용 매개 변수. out (0) | 2017.03.24 |
[C#] 공용 형식 시스템. (0) | 2017.03.24 |
[C#] Object형식, 박싱과 언박싱. (1) | 2017.03.23 |
[C#] 값 형식과 참조형식 (0) | 2017.03.23 |
[C#] Object형식, 박싱과 언박싱.
1. Object형식
object형식은 "상속" 덕분에 어떤 데이터든지 다룰수 있는 데이터 형식이다.
C#은 object가 모든 데이터를 다룰 수 있도록 하기 위해 특별 조치를 취했는데,
모든 데이터 형식이 자동으로 object형식으로부터 상속받게 한 것이다.
다시 말해 object형식이 모든 데이터 형식의 부모라고 하면 된다.
※ 모든 데이터 형식이 가능하다. 프로그래머가 만든 데이터 형식도 마찬가지다.
따라서 컴파일러는 어떤 형식의 데이터라도 object에 담아 처리할 수 있게 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System namespace Object { class Test { static void Main(string[] args) { object a = 100; object b = 3.14; object c = true; object d = "헬로우 월드"; Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(c); Console.WriteLine(d); } } } | cs |
각 자료형이 처리하는 방식이 다른데 어떻게 이런일이 가능할까?
우리는 그걸 알기 위해 이 뒤에 일어나는 메커니즘을 이해할 필요가 있다.
그 메커니즘을 박싱, 언박싱 이라고 한다.
2. 박싱과 언박싱
object형식은 참조 형식이기 때문에 힙에 데이터를 할당한다.
int나 double 형식은 값 형식이기 때문에 스택에 할당한다.
그런데 앞에서 값 형식의 데이터를 object형식 객체에 담았다.
이 경우는 어느 메모리에 데이터가 할당될까?
object형식은 값 형식의 데이터를 힙에 할당하기 위한 박싱(Boxing)기능을 제공한다.
object형식에 값 형식의 데이터를 할당하려는 시도가 이루어지면 object형식은 박싱을 수행해서 해당 데이터를 힙에 할당한다.
이렇게 박싱이 일어나는 한 편, 힙에 있던 값 형식 데이터를 값 형식 객체에 다시 할당해야 하는 경우가 있다.
다음이 그런 경우다.
1 2 | object a = 20; int b = (int)a; | cs |
위 코드에서 a는 20이 박싱되어 저장되어 있는 힙을 참조하고 있다.
b는 a가 참조하고 있는 메모리로부터 값을 복사하려고 하는 중이다.
이 때, 박싱되어 있는 값을 꺼내 값 형식 변수에 저장하는 과정을 언박싱(UnBoxing)이라고 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | using System; namespace BoxingUnBoxing { class MainApp { static void Main(string[] args) { int a = 123; object b = (object)a; // a에 담긴 값을 박싱하여 힙에 저장 int c = (int)b; // b에 담긴 값은 언박싱하여 스택에 저장 Console.WriteLine(a); // 결과 : 123 Console.WriteLine(b); // 결과 : 123 Console.WriteLine(c); // 결과 : 123 } } } | cs |
'C#' 카테고리의 다른 글
[C#] 메소드 오버로딩, 가변길이 매개 변수, 선택적 매개 변수 (0) | 2017.03.25 |
---|---|
[C#] 참조에 의한 매개 변수 전달. ref / 출력 전용 매개 변수. out (0) | 2017.03.24 |
[C#] 공용 형식 시스템. (0) | 2017.03.24 |
[C#] var형식 (0) | 2017.03.24 |
[C#] 값 형식과 참조형식 (0) | 2017.03.23 |