C++ Data Types
C++의 모든 타입은 기본 타입, 파생 타입, 사용자 정의 타입으로 구분할 수 있다.
기본 타입 (Primary Type)
기본 타입은 C++에서 기본적으로 사용되는 타입들을 의미한다.
다음과 같은 기본 타입들이 존재한다.
// primitive types
bool a = false;
char b = 'a';
unsigned char c = 255;
short d = 32767;
unsigned short e = 65535;
int f = 2147438647;
unsigned int g = 4294967295;
long h = 2147438647;
unsigned long i = 4294967295;
long long j = 9223372036854775807;
unsigned long long k = 18446744073709551615;
float l = 10.0f;
double m = 10;
// void 타입은 변수로는 정의가 불가능하지만, 함수의 리턴이나 void*로는 정의가 가능하다.
사용자 정의 타입 (User Defined Type)
사용자 정의 타입은 프로그래머가 직접 정의하는 타입들을 의미한다.
다음과 같은 사용자 정의 타입들이 존재한다.
// user defined types
Enum enumType;
Struct structType;
Class classType;
// container types
string str = "10";
// 동적 배열
vector<int> vec;
vector<string> svev;
// 연결 리스트
list<int> ll;
stack<int> st;
queue<int> que;
// 힙
priority_queue<int> heap;
// 정렬 딕셔너리
map<int, int> mm;
// 비정렬 딕셔너리
unordered_map<int, int> umap;
// 정렬 집합
set<int> ss;
// 비정렬 집합
unordered_set<int> uset;
파생 타입
기본 또는 사용자 정의 데이터 타입에서 파생 된 데이터 타입들을 파생 데이터 타입이라고 한다.
다음과 같은 파생 타입들이 존재한다.
포인터 타입
포인터 타입은 어떤 타입이 정의되어 있을 때, 그 타입의 메모리를 참조할 수 있는 타입을 의미한다.
모든 일반 타입에 대한 포인터 타입을 정의할 수 있다.
// pointer types
{
// primitive types
char* pb = &b;
int* pf = &f;
float* pl = &l;
double* pm = &m;
void* pvoid = nullptr;
// user defined types
string* pstr = &str;
Enum* penumType = &enumType;
Struct* pstructType = &structType;
Class* pclassType = &classType;
// container types
vector<int>* pv = &vec;
list<int>* pll = ≪
stack<int>* ps = &st;
queue<int>* pq = &que;
priority_queue<int>* ph = &heap;
map<int, int>* pmm = &mm;
unordered_map<int, int>* pum = &umap;
set<int>* pss = &ss;
unordered_set<int>* pus = &uset;
// function pointer types
void (*name) (int) = &foo;
}
레퍼런스 타입
레퍼런스 타입은 태생적으로 포인터 타입과 같다.
애초에 레퍼런스 타입이 만들어진 이유가 포인터 타입을 좀 더 안전하게, 좀 더 편하게 사용하기 위함이다.
몇가지 차이점은 다음과 같다.
1. 레퍼런스 타입은 포인터 타입과 달리 선언과 동시에 다른 변수를 참조하며 초기화되어야 한다.
2. 레퍼런스 타입은 NULL이 될 수 없다. (NULL을 참조할 수 없다)
3. 레퍼런스 타입은 이름으로 바로 사용할 수 있다. (포인터 타입보다 편하다.)
int a = 5;
int *pa = &a;
int& ra = a;
// 사용할 때
// 역참조 후 사용 가능하다.
*pa = 3;
// 일반 변수처럼 바로 사용 가능하다.
ra = 3;
4. 레퍼런스 타입은 한번 초기화된 후에는 다른 변수를 참조할 수 없다.
모든 일반 타입에 대한 레퍼런스 타입을 정의할 수 있다.
// reference types
{
// primitive types
char& rb = b;
int& rf = f;
float& rl = l;
double& rm = m;
// user defined types
string& rstr = str;
Enum& renumType = enumType;
Struct& rstructType = structType;
Class& rclassType = classType;
// container types
vector<int>& rv = vec;
list<int>& rll = ll;
stack<int>& rs = st;
queue<int>& rq = que;
priority_queue<int>& rh = heap;
map<int, int>& rmm = mm;
unordered_map<int, int>& rum = umap;
set<int>& rss = ss;
unordered_set<int>& rus = uset;
}
배열 타입
배열 타입은 태생적으로 포인터 타입과 같다.
몇가지 차이점은 다음과 같다.
1. 배열 타입은 컴파일 타임에서 메모리에 대한 블록 설정을 해주기 때문에, 할당된 메모리를 벗어나지 않도록 방지해준다. (포인터 타입으로도 충분히 배열 타입과 같은 연산을 할 수 있지만, 바운더리가 없기 때문에 위험할 수 있다.)
2. 배열 타입은 포인터 타입과 달리 invalid한 타입으로 초기화가 불가능하다.
모든 일반 타입에 대한 배열 타입을 정의할 수 있다.
// array types
{
// primitive types
int aa[3];
float ab[3];
double ac[3];
char ad[3];
// user defined types
string astr[3];
Enum aenumType[3];
Struct astructType[3];
Class aclassType[3];
// container types
vector<int> av[3];
list<int> al[3];
stack<int> as[3];
queue<int> aq[3];
priority_queue<int> ah[3];
map<int, int> am[3];
unordered_map<int, int> aum[3];
set<int> ass[3];
unordered_set<int> aus[3];
// function pointer types
void (*arrname[]) (int) { &foo };
}
조합
다음과 같은 타입들은 서로 조합되어 사용되기도 한다.
포인터에 대한 포인터 (가능)
int* p;
int** pp = &p;
포인터에 대한 레퍼런스 (가능)
int* p;
int*& rp = p;
포인터에 대한 배열 (가능)
int* p = nullptr;
int* rp[3] = { p, p, p };
레퍼런스에 대한 포인터 (불가능)
int t;
int& r = t;
int&* rp = r;
의미가 있을까?
레퍼런스에 대한 레퍼런스 (불가능)
int a;
int& t = a;
int&& r = t;
의미가 있을까?
&& 연산자는 애초에 rvalue 레퍼런스라는 완전 다른 개념으로 사용된다.
레퍼런스에 대한 배열 (불가능)
int a;
int& t = a;
int& r[] = { t };
레퍼런스에 대한 포인터와 다를 바 없다.
배열에 대한 포인터 (가능)
int a[5] = { 1, 2, 3, 4, 5 };
int (*pa)[5] = &a;
배열에 대한 레퍼런스 (가능)
int a[] = { 1, 2, 3, 4, 5 };
int(&ra)[5] = a;
배열에 대한 배열 (가능)
int aa[5][5] = { {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5} };
'프로그래밍 > C++' 카테고리의 다른 글
[C++] C++에서 Partial Class 구현 방법 (0) | 2023.09.23 |
---|---|
[C++] C++에서 Interface 구현 방법 (0) | 2023.09.23 |
[C++] Casting 총정리 (0) | 2023.09.23 |
[C++] 객체 복사 (0) | 2021.04.27 |
[C++] friend (2) | 2021.04.06 |