기본 형식
Fundamental types in C++ are divided into three categories: integral, floating point, and void. Integral types are capable of handling whole numbers. Floating point types are capable of specifying values that may have fractional parts.
The void type describes an empty set of values. No variable of type void can be specified — it is used primarily to declare functions that return no values or to declare generic pointers to untyped or arbitrarily typed data. Any expression can be explicitly converted or cast to type void. However, such expressions are restricted to the following uses:
-
An expression statement. (See Expressions, for more information.)
-
The left operand of the comma operator. (See Comma Operator for more information.)
-
The second or third operand of the conditional operator (? :). (See Expressions with the Conditional Operator for more information.)
The following table explains the restrictions on type sizes. These restrictions are independent of the Microsoft implementation.
C++ 기본 형식은 정수형, 부동소수점 그리고 void 이 세 가지 형식으로 구분된다. 이 중 두 가지 정수형과 부동소수점은 학창시절 수학시간에 들어봤으니 친숙할 것이다. 정수형은 정수(整數, Integer)를 처리할 수 있고 부동소수점(浮動小數點, floating point)은 정수부와 소수부를 따로 처리하는 방식이다. 혹여, 더 자세한 경우를 알아야할 경우가 있으니 아래쪽에 링크를 걸겠다.
void 형식은 단어 표현 그대로 빈 값을 나타낸다. (1.)형식이 정해지지 않거나 (2.)함수에서 반환값이 없거나 마지막으로 (3.)포인터의 형식이 정해지지 않았음을 알려주는 것이 바로 void이다. 만약 자료형 변환을 시행했을 때 마땅한 형식이 정해지지 않았으면 void형으로 변환이 될 것이다. 자세한 것은 아래에 서술하겠다.
정수(整數, Integer)_
부동소수점(浮動小數點, floating point)_
nullptr
어떠한 원시 포인터 형식으로도 변환될 수 있는 std::nullptr_t 형식의 null 포인터 상수를 지정합니다. 헤더를 포함하지 않고 nullptr 키워드를 사용할 수 있지만, 코드에서 std::nullptr_t 형식을 사용하는 경우 <cstddef> 헤더를 포함하여 정의해야 합니다.
참고
nullptr 키워드는 관리 코드 응용 프로그램을 위해 C++/CLI에서도 정의되며 ISO 표준 C++ 키워드와 상호 교환해서 사용할 수 없습니다. 관리 코드를 대상으로 하는 /clr 컴파일러 옵션을 사용하여 코드를 컴파일할 수 있는 경우, 컴파일러에서 네이티브 C++ 해석을 사용하도록 보장해야 하는 코드의 모든 줄에서 __nullptr을 사용합니다. 자세한 내용은 nullptr을 참조하십시오.
설명
NULL 또는 영(0)을 null 포인터 상수로 사용하지 마십시오. nullptr은 잘못 사용하는 경우 위험성이 더 적고 대부분의 상황에서 보다 효과적으로 작동합니다. 예를 들어 func(std::pair<const char *, double>)가 주어진 경우 func(std::make_pair(NULL, 3.14))를 호출하면 컴파일러 오류가 발생합니다. NULL 매크로는 0으로 확장되므로 std::make_pair(0, 3.14) 호출은 func()의 std::pair<const char *, double> 매개 변수 형식으로 변환될 수 없는 std::pair<int, double>를 반환합니다.std::make_pair(nullptr, 3.14)는 std::pair<const char *, double>로 변환될 수 있는 std::pair<std::nullptr_t, double>를 반환하기 때문에 func(std::make_pair(nullptr, 3.14))를 호출하면 성공적으로 컴파일됩니다.
참고 항목
인류 수학의 가장 위대한 발견 중 하나가 0이란 말도 들은 적 있는 것 같다. 또한 5차원 이상의 [근의 공식이 없다]는 증명도 굉장히 획기적인 발견이었다. 이렇듯 흔히 일상생활에서 [없다]를 생각하는 경우는 드물 수 있다.
프로그래밍에서도 [없다]를 체크하는 경우가 필요하다. 바로 C++ 핵심인 포인터가 [없는 것을 가리키는 것]. 예전에야 nullptr이 0 을 대변해 이런저런 오류를 범했지만 이제는 nullptr은 본연의 임무인 0이 아닌 완전히 [없는] 것을 가리키게 되었다. 이는 여타 다른 언어에서도 중요한 이점을 차지한다. 이 개념은 C++/CLI에서도 적용이 되는 것을 볼 수 있다.
일반적으로 그냥 nullptr 키워드를 사용할 수 있지만 std::nullptr_t 를 사용할 경우 헤더 <cstddef> 를 추가해야 한다.
더 자세한 설명은 위 접은글을 참고하기 바란다.
void
함수 반환 형식으로 사용된 경우 void 키워드는 함수가 값을 반환하지 않도록 지정합니다. 함수의 매개 변수 목록에 사용된 경우 void는 함수가 매개 변수를 사용하지 않도록 지정합니다. 포인터 선언에 사용된 경우 void는 포인터를 '범용'으로 지정합니다.
포인터 형식이 void *이면 포인터가 const 또는 volatile 키워드로 선언되지 않은 모든 변수를 가리킬 수 있습니다. void 포인터는 다른 형식으로 캐스팅되지 않은 경우 역참조할 수 없습니다. void 포인터를 다른 형식의 데이터 포인터로 변환할 수 있습니다.
void 포인터는 함수를 가리킬 수 있지만 C++의 클래스 멤버는 가리킬 수 없습니다.
void 형식의 변수는 선언할 수 없습니다.
참고자료
예제
1
2
3
4
5
6
7
8
9
|
// void.cpp
void vobject; // C2182
void *pv; // okay
int *pint; int i;
int main() {
pv = &i;
// Cast optional in C required in C++
pint = (int *)pv;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter
|
우선 void 자료형 선언은 허용은 된다. 지금 당장 VS2019에 들어가서 void 형 선언을 해보면 알 수 있다. 다만, 역시 컴파일이 안 된다. 이는 엄연히 [void]가 [자료형]으로서 틀리지 않는 문법을 갖추었다는 것을 의미한다. 자료형으로서 제 역할을 수행할 수 있으며, 다만 컴파일 과정에서 실수나 틀린 부분을 맞추어주는 식이다.
void를 어떻게 쓰는 지 위 글을 바탕으로 정리를 하였다.
- void는 함수가 값을 반환하지 않도록 지정한다.
- void는 함수가 매개변수를 사용하지 않도록 한다.
- void 포인터는 [범용]으로 지정한다.
- void 포인터는 const 혹은 volatile 키워드로 선언되지 않은 모든 변수를 가리킬 수 있다. [범용]
- 다른 형식으로 캐스팅 되지 않으면 역참조를 할 수 없다.
- void 포인터는 다른 형식의 데이터 포인터로 변환될 수 있다.
- 함수는 가리킬 수 있지만 클래스 맴버는 가리킬 수 없다.
- void 형식의 변수는 선언할 수 없다.
C++ 언어의 기본 형식
형식 | 코드 | 크기(Byte) | 설명 | 범위 |
정수형 | char | 1 | 기본 문자집합을 포함한다. 이는 C++ 내 ASCII 코드이다. |
-128 ~ 127 CHAR_MIN |
bool | 1 | 참과 거짓 두 값 중 하나만 가질 수 있는 정수 계열 형식이다. 크기는 지정되지 않는다. | 참 또는 거짓 | |
short (short int, |
2 |
short int라고도 하며, 짧게 그냥 short라 한다. 같은 정수형 계열인 char보다는 크고 int 보다는 작거나 같은 자료형이다. Type short int (or simply short) is an integral type that is larger than or equal to the size of type char, and shorter than or equal to the size of type int. |
-32,768 ~ 32,767 SHRT_MIN |
|
int (unsigned int) |
4 |
short 보다 크고 long보다 작거나 같은 자료형이다. Type int is an integral type that is larger than or equal to the size of type short int, and shorter than or equal to the size of type long. |
-2,147,483,648 ~ 2,147,483,647 INT_MIN |
|
__int8, __int16, __int32, __int64, |
각각 1,2,4,8 |
크기가 지정된 정수 형식이다. Microsoft전용 키워드이며 모든 형식에 사용되지 않을 수 있다. (__int128은 지원하지 않는다.) |
||
long (long int) |
4 |
int 보다 크거나 같은 자료형이다. Type long (or long int) is an integral type that is larger than or equal to the size of type int. |
-2,147,483,648 ~ 2,147,483,647 LONG_MIN |
|
long long | 8 | long 보다 큰 자료형이다. |
-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 LLONG_MIN |
|
wchar_t, __wchar_t | 2 |
Wide-Character 혹은 Multibyte Character을 지원하는 자료형이며, native 형이다. 그리고 /Zc:wchar_t 를 이용해 wchar_t를 unsigned short 로 치환할 수 있다. A variable of type wchar_t designates a wide-character or multibyte character type. By default, wchar_t is a native type, but you can use /Zc:wchar_t- to make wchar_t a typedef for unsigned short. The __wchar_t type is a Microsoft-specific synonym for the native wchar_t type. |
0 ~ 65,535 | |
부동소수점 | float | 4 | 가장 작은 단위의 부동소수점 형이다. |
3.4E +/- 38 (소수점 7 자리) FLT_MIN |
double | 8 |
float형보단 크지만 long double 보단 작은 형이다. long double과 같은 표현방식이지만 자료형으로선 분리된 형이다. Microsoft specific: The representation of long double and double is identical. However, long double and double are separate types. |
1.7E +/- 308 (소수점 15자리) DLB_MIN |
|
long double | double과 같다. |
double과 같거나 큰 자료형이다. Type long double is a floating point type that is larger than or equal to type double. |
double과 같다. LDBL_MIN |
정수 제한 매크로 - https://docs.microsoft.com/ko-kr/cpp/cpp/integer-limits?view=vs-2019
부동소수점 제한 매크로 - https://docs.microsoft.com/ko-kr/cpp/cpp/floating-limits?view=vs-2019
참고로 true == 1, false == 0 이다...
Basic Character 문자 기본 집합
기본 소스 문자 집합 은 소스 파일에서 사용할 수 있는 96개 문자로 구성됩니다. 이 집합에는 공백 문자, 가로 탭, 세로 탭, 폼 피드 및 줄 바꿈 제어 문자가 포함되며 다음 그래픽 문자 집합도 포함됩니다.
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
출처 - https://docs.microsoft.com/ko-kr/cpp/cpp/character-sets?view=vs-2019
문자는 1Byte 크기이며, 자료형 char에 담길 수 있다.
Wide Character 와 Multi Character의 차이
멀티바이트 및 와이드 문자
멀티바이트 문자는 하나 이상의 바이트의 시퀀스로 구성된 문자입니다. 각 바이트 시퀀스는 확장된 문자 집합에서 단일 문자를 나타냅니다. 멀티바이트 문자는 한자와 같은 문자 집합에 사용됩니다.
와이드 문자는 항상 16비트 크기의 다국어 문자 코드입니다. 문자 상수 형식은 char이며 와이드 문자 형식은 wchar_t입니다. 와이드 문자의 크기는 항상 고정되어 있으므로 와이드 문자를 사용하면 국제 공용 문자 집합으로 단순하게 프로그래밍할 수 있습니다.
출처 - https://docs.microsoft.com/ko-kr/cpp/c-language/multibyte-and-wide-characters?view=vs-2019
위 단락에서 중요한 부분에 밑줄을 그어 보자면...
멀티바이트 문자는 하나 이상의 바이트의 시퀀스로 구성된 문자입니다.
와이드 문자는 항상 16비트 크기의 다국어 문자 코드입니다.
멀티바이트는 말 그대로 멀티... 여러 개의 크기를 가진다 하여 붙혀진 이름이고, 와이드 문자는 아예 [확장문자]라는 단어로 칭한다. 멀티바이트에서는 영어 알파벳과 같은 글자는 1바이트로 처리되고 크기가 큰 문자는 2바이트로 처리된다.
반면에, 와이드 바이트에서는 글자 크기가 작든 크든 무조건 2바이트로 처리된다.
이는 시대가 변함에 따라 저장소가 방대해진 까닭에 글자 하나를 2바이트 정도로 확장해도 메모리 관리에 전혀 지장이 없어졌다. 오히려 크기가 다르게 저장하는 것이 비효율적이게 되었다.
참고 - https://ko.wikipedia.org/wiki/%ED%99%95%EC%9E%A5_%EB%AC%B8%EC%9E%90
멀티든 와이드든 둘 다 wchar_t에 담길 수 있다.
크기별 정리
크기(byte) | 자료형 |
1 | bool, char, unsigned char, signed char, __int8 |
2 | __int16, short, unsigned short, wchar_t, __wchar_t |
4 | float, __int32, int, unsigned int, long, unsigned long |
8 | double, __int64, long double, long long |
__m 시리즈
__m64 - https://docs.microsoft.com/ko-kr/cpp/cpp/m64?view=vs-2019
__m128 - https://docs.microsoft.com/ko-kr/cpp/cpp/m128?view=vs-2019
__m128d - https://docs.microsoft.com/ko-kr/cpp/cpp/m128d?view=vs-2019
__m128i - https://docs.microsoft.com/ko-kr/cpp/cpp/m128i?view=vs-2019
__m64 | __m128 | __m128d | __m128i | |
정렬 | 8바이트 경계 | 16바이트 경계 | ||
매핑 레지스터 | MM[0-7] | XMM[0-7] | ||
데이터 유형 | MMX 3DNow! |
SIMD SSE2 |
Streaming SIMD Extensions 2 (SSE2) instructions intrinsics | |
x64 지원 여부 | x | o | ||
ARM 지원 여부 | x | |||
참고 |
...더보기
MMX 내장 함수의 일부로 __m64를 사용하는 응용 프로그램은 동등한 SSE 및 SSE2 내장 함수를 사용하도록 다시 작성해야 합니다. |
...더보기
__m128i 형식의 변수를 사용하면 컴파일러에서 SSE2 movdqa 명령이 생성됩니다. 이 지침은 펜티엄 III 프로세서에서 오류를 발생시키지는 않지만, 펜티엄 III 프로세서에서 지침 movdqa가 이동하는 일부 유형에 대해 자동으로 실패하는 부작용이 있을 수 있습니다. |
||
공통 헤더 | #include <xmmintrin.h> |
#include <emmintrin.h> | ||
공통점 | ARM 프로세서에서 지원되지 않는다. |
해당 표는 위 주소들에서 제공하는 정보들을 바탕으로 정리한 것이다. 헷갈리거나 좀더 확실한 답을 얻고 싶으면 들어가거나 따로 알아보기 바란다.
XMM[0-7] 레지스터 참고 포탈
__ptr32, __ptr64
Microsoft Specific
__ptr32 represents a native pointer on a 32-bit system, while __ptr64 represents a native pointer on a 64-bit system.
The following example shows how to declare each of these pointer types:
C++복사
int * __ptr32 p32; int * __ptr64 p64;
On a 32-bit system, a pointer declared with __ptr64 is truncated to a 32-bit pointer.On a 64-bit system, a pointer declared with __ptr32 is coerced to a 64-bit pointer.
참고
You cannot use __ptr32 or __ptr64 when compiling with /clr:pure. Otherwise, Compiler Error C2472 will be generated. The /clr:pure and /clr:safe compiler options are deprecated in Visual Studio 2015 and unsupported in Visual Studio 2017.
For compatibility with previous versions, _ptr32 and _ptr64 are synonyms for __ptr32and __ptr64 unless compiler option /Za (Disable language extensions) is specified.
Example
The following example shows how to declare and allocate pointers with the __ptr32and __ptr64 keywords.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <cstdlib>
#include <iostream>
int main()
{
using namespace std;
int * __ptr32 p32;
int * __ptr64 p64;
p32 = (int * __ptr32)malloc(4);
*p32 = 32;
cout << *p32 << endl;
p64 = (int * __ptr64)malloc(4);
*p64 = 64;
cout << *p64 << endl;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter
|
Output:
1
2
|
32
64
|
__ptr32을 x64 운영체제에서 사용하면 자동으로 형변환이 되고 __ptr64를 x86에서 사용하면 나머지 부분이 잘린다고 표현했다. 하지만, 해당 예제를 x64에서 실행하면 터졌다. __ptr32에 메모리 할당을 하지 못하면서 일어나는 오류였다.
해당 포인터들의 크기는 각각 다음과 같았다.
Code:
1
2
3
4
5
6
7
8
9
10
|
int __cdecl main(void)
{
using namespace std;
int* __ptr32 p32;
int* __ptr64 p64;
cout << "x86 Pointer size: " << sizeof(p32) << endl;
cout << "x64 Pointer size: " << sizeof(p64) << endl;
}
|
Output:
1
2
|
x86 Pointer size: 4
x64 Pointer size: 8
|
해당 글은 순전히 마이크로소프트에서 제공하는 [기본자료형]만을 포스팅했다. 이 자료형들로 충분히 더 크거나 더 세밀한 자료형을 직접 만들 수 있을 것이며, 이를 사용자지정 자료형이라 구분지으면 될 것 같다. 그렇게 되면 수많은 자료형이 존재하겠지만 앞으로 이어질 함수나 개념설명들은 이 자료형에 기반이 되어 설명이 되므로 꼭 짚고 넘어가야할 부분이었다.
'C++' 카테고리의 다른 글
연산자 static_cast + const_cast + reinterpret_cast (0) | 2019.06.26 |
---|---|
키워드 - cast, casting + 연산자 dynamic_cast + 예외 bad_cast + type-id, typeinfo (0) | 2019.06.21 |
바이트 패딩 - 비트 필드 (0) | 2019.06.19 |
함수 호출 규약 - __thiscall, __clrcall (0) | 2019.06.18 |
함수 호출 규약 - __fastcall, __vectorcall (0) | 2019.06.14 |