일반 자료형
- 정수 계열 자료형
데이터 형식 | 부호 유무 | 크기 | C++ 자료형 |
byte | x | 1바이트 | unsigned char |
sbyte | o | 1바이트 | char |
short | o | 2바이트 | short |
ushort | x | 2바이트 | unsigned short |
int | o | 4바이트 | int |
uint | x | 4바이트 | unsigned int |
long | o | 8바이트 | long long int |
ulong | x | 8바이트 | unsigned long long int |
char | 유니코드 문자 | 2바이트 | unsigned char |
- 부동 소수점
데이터 형식 | 설명 | 크기 |
float | 단일 정밀도 (7개 자릿수) | 4바이트 |
double | 복수 정밀도 (15~16개 자릿수) | 8바이트 |
decimal | 29자리 데이터를 표현 | 16바이트 |
- 논리형
데이터 형식 | 크기 | 값 |
bool | 1바이트 | true, false |
Object 형식
모든 데이터 형식의 조상 클래스로 어떠한 형식의 데이터라도 담을 수 있는 특징이 있다.
- 박싱과 언박싱
object 형식은 참조 형식으로 힙에 데이터를 할당한다. 실제 값을 힙 메모리에 저장하고 스택에서는 포인터 형식으로 힙 메모리를 참조하고 있다. 다른 형식에 object 값을 대입하면 힙 메모리를 참조하여 실제 값을 가져와 다른 형식의 값에 할당하는 구조로 되어있다.
- 예시
class MainApp
{
static void Main(string[] args)
{
int a = 123;
object b = (object)a; // a에 담긴 값을 박싱해서 힙에 저장
int c = (int)b; // b에 담긴 값을 언박싱해서 스택에 저장
Console.Write(a); // 123
Console.Write(b); // 123
Console.Write(c); // 123
Console.Read();
}
}
Nullable 형식
변수의 메모리 할당을 유보할 수 있는 형식이다. 즉, Nullable 형식은 null을 대입하여 지금 메모리 공간을 할당하지 않고 나중에 값을 대입할 때, 메모리 할당이 일어난다. C++에서 포인터 선언만 해두고 동적 할당을 나중에 하는 것과 같은 원리.
따라서 실제 값을 참조하기전 Nullable 변수에 대해 메모리 할당이 되어 있는지 HasValue 혹은 null과 == 논리연산으로 검사해야한다. C++의 포인터 혹은 std::optional와 유사하다.
참고 (std::optional): https://en.cppreference.com/w/cpp/utility/optional
데이터 형식 이름뒤에 ?을 붙여 선언하고 null을 다시 대입한다면 할당된 메모리가 해제된다.
- 예시
namespace HelloWorld
{
class MainApp
{
static void Main(string[] args)
{
int? a = null; // 메모리 할당 유보
Console.WriteLine(a.HasValue); // false
Console.WriteLine(a == null); // true
a = 3; // 메모리 할당과 값 대입
Console.WriteLine(a.HasValue); // true
Console.WriteLine(a == null); // false
Console.WriteLine(a.Value); // 3
a = null; // 메모리 해제
Console.WriteLine(a.HasValue); // false
Console.WriteLine(a == null); // true
Console.Read();
}
}
}
var 형식
C++11 auto와 같다. 컴파일러가 문맥을 파악하여 변수의 타입을 자동으로 지정해준다. auto와 마찬가지로 타입을 추론하기 위해 반드시 변수 선언과 동시에 값을 대입하여야 한다.
namespace HelloWorld
{
class MainApp
{
static void Main(string[] args)
{
var a = 3; // a는 int 형식
var b = "Hello"; // b는 string 형식
}
}
}
vs Object 형식을 이용한 초기화
Object 형식은 값 대입시 힙 메모리를 사용한다는 점과 var 형식은 컴파일러가 컴파일 타입에 타입을 추론하여 예시에서 처럼 int로 치환하여 int만큼의 스택 메모리를 사용하게 된다.
namespace HelloWorld
{
class MainApp
{
static void Main(string[] args)
{
var a = 10; // 값 저장을 위해 스택 메모리를 사용
Object b = 10; // 값 저장을 위해 힙 메모리를 사용, b는 힙 메모리를 가리키는 스택 메모리 변수
}
}
}
공용 형식 시스템 (CTS : Common Type System)
마이크로소프트가 C#을 비롯하여 .NET을 지원하는 모든 언어에서 호환이 가능하도록 공용 형식 시스템을 도입하였다. 따라서 모든 .Net 프로그램은 공용 형식 시스템을 사용하기 때문에 개발한 플랫폼과 다른 플랫폼에서 쉽게 .Net 프로그램을 이식할 수 있게 되었다.
공용 형식 시스템 CTS에서 사용되는 공통 형식은 System.xxx로 명칭되며 C#에서 사용되는 모든 자료형은 공용 타입 클래스 중 하나와 같거나 상속한 것이다.
모든 데이터 형식은 Object 형식 (System.Object)를 상속하기 때문에 GetType()과 ToString()과 같은 메서드를 사용할 수 있다.
.Net의 공용 형식 시스템
참고 : https://docs.microsoft.com/ko-kr/dotnet/standard/base-types/common-type-system#enumerations