C++에서 사용하는 데이터 형식

1. 데이터 형식

 

변수는 '값을 저장할 수 있는 공간'

 

C++ 언어에서는 변수에 값을 저장하기 전에 정수, 부동 소수점, 문자 등 어떤 값을 저장할지 미리 정해주어야함

 

이를 데이터 형식(자료형)이라고 한다

 

파이썬 같은 인터프리터 언어는 변수의 형식을 자동으로 결정해주는데 C++같은 컴파일 언어는 형식을 직접 지정해주어야함

 

형식이 엄격한 C++같은 언어는 변수를 선언하고 사용할 때 어떤 형식으로 만들지 항상 고민해야하는데, 

 

파이썬같은 형식이 유연한 언어보다 훨씬 까다롭지만, 런타임 오류도 줄고 메모리를 효율적으로 이용할 수 있는 장점도 있다

 

 

형식 키워드 크기(byte) 특징
보이드 void none '형식 없음'
불리언 bool 1 true, false
문자 char 1 8비트 정수형으로 사용될 경우 일반적으로 -128~127
unsigned char 1 0~255
signed char 1 부호 비트를 가지도록 명시적으로 표현
char8_t 1 C++20 새 형식
char16_t 2 UTF-16 문자 표현에 사용
char32_t 4 UTF-32 문자 표현에 사용
wchar_t 2 와이드 문자(wide char) 표현
__wchar_t 2 마이크로소프트 전용
정수 short 2 적어도 char보다는 크기가 큰 정수
unsigned short 2 양수만 저장
int  4 일반적으로 가장 많이 사용
unsigned int 4 양수만
__int8 1 마이크로소프트 전용 정수
__int8은 char과 동일 취급
__int16은 short, __int32는 int, __int64는 long long와 같은 데이터 형식 취급
__int16 2
__int32 4
__int64 8
long 4 long의 경우 32비트 운영체제에서는 4byte,
64비트 운영체제에서는 8byte

윈도우 64비트에서는 long도 4byte
unsigned long 4 양수만
long long 8 int형 연산에서 초과되는 범위를 다룰때 사용하고 적어도 8byte 이상 크기 보장
unsigned long long 8 양수만
부동 소수점 float 4 C++언어에서 가장 작은 부동 소수점
double 8 float보다 큰 부동 소수점 형식, 소수를 구하는 연산에서는 double이 소수점 아래 표현을 더 많이 할 수 있어 double 추천
long double 8 GCC, G++에서 long double는 16byte

 

 

__int8. __wchar_t 처럼 데이터 형식 앞에 __이 붙으면 마이크로소프트에서 제공하는 확장형

 

마이크로소프트 비주얼 C++에서만 인식

 

특정 환경에서만 지원되므로 호환성이 떨어질 수 있어 int8_t, wchar_t같은 표준 C++ 자료형을 사용하는 것을 추천

 

 

2. void

 

void는 형식이 없음을 뜻함

 

그래서 void value;처럼 선언할 수 없음

 

etc-image-0

 

 

1) 함수가 값을 반환하지 않음을 표시할 때

 

다음 print_func()는 값을 반환하는 return이 없는데, 반환값이 없는 함수를 선언할 때 void를 표시함

 

void print_func() {
	std::cout << "func" << std::endl;
}

 

 

2) 함수의 매개변수가 없음을 표시할 때

 

함수의 매개변수가 없으면 print_func()처럼 아무것도 입력하지 않은 채 ()처럼 빈 괄호로 두어도 된다.

 

하지만 input_func(void)처럼 명시적으로 표현할 수 있다

 

int input_func(void) {
	int input_value;
	std::cin >> input_value;
	return input_value;
}

 

 

3) 모든 자료형을 가리킬 수 있는 제네릭 포인터(generic pointer)

 

어떤 변수라도 가리킬 수 있는 제네릭 포인터를 만들 때 사용가능

 

제네릭 포인터에서 void는 단순히 '형태가 없음'이라기 보다는 '형태가 자유로움'을 의미함

 

int main() {

	int int_value;
	float float_value;
	void *ptr_value; //제네릭 포인터
	ptr_value = &int_value;
	ptr_value = &float_value;

	return 0;
}

 

 

3. bool

 

bool은 참(true, 1)과 거짓(false, 0)만 가질 수 있다

 

bool형 변수에 true,false를 넣어 초기화할 수 있지만, 실제로는 1,0 정수로 저장된다

 

#include <iostream>
using namespace std;

int main(){
	
	bool value;

	value = true;
	cout << value << endl;

	value = false;
	cout << value << endl;

	return 0;
}

 

 

etc-image-1

 

 

 

4. 문자 형식

 

char은 C++에서 문자를 다룰 때 사용하는 대표적인 데이터 형식이지만 8bit 정수를 저장하는 역할을 할 뿐

 

문자 전용 데이터 형식은 아니다.

 

char에 저장된 값은 아스키 코드로 변환하여 사용할 수 있다

 

etc-image-2

 

 

 

문자로 출력할 수 있는 것은 32~126번

 

#include <iostream>
using namespace std;

int main(){
	
	cout << "아스키 코드 출력하기 [32 ~ 126]:\n";

	for (char i = 32; i <= 126; i++) { //32부터 126까지 1씩 증가하며 반복

		//아스키 코드를 출력할 때 공백을 넣고 16개마다 줄 바꾸기
		cout << i << ((i % 16 == 15) ? '\n' : ' ');
	}

	return 0;
}

 

 

 

etc-image-3

 

 

 

문자를 표현하는 데 char을 사용하는 이유는 아스키코드가 7bit 형태의 체계를 따르기 때문

 

나머지 1bit는 통신 확인용 패리티 비트

 

char이 아스키 문자를 저장할 때는 0 ~ 127사이 값을 가진다

 

만약 char을 8bit 정수 저장용으로 사용한다면 1bit를 부호로 사용하여 -128~127을 저장

 

unsigned char은 부호 비트까지 써서 0~255까지 저장

 

etc-image-4

 

 

wchar_t는 와이드 문자를 저장하는 자료형

 

비주얼 스튜디오에서는 wchar_t를 2byte로 정의하고 GCC 컴파일러는 4byte로 정의

 

하지만 GCC에서도 컴파일할 때 -fshort-wchar 옵션을 적용해서 wchar_t를 2byte로 사용가능

 

구분 char wchar_t
인코딩 멀티바이트(MBCS) 유니코드(UNICODE)
단일 문자 크기 1byte 또는 2byte
(영문 숫자 등의 아스키 코드는 1byte, 한글, 한자 등은 2byte로 표현)
2byte(GCC에서는 기본 4byte)
문자열 유니코드를 제외한 문자열(ANISI, UTF-8) 와이드 문자, UTF-16으로 인코딩된 문자열

 

 

UTF-16으로 인코딩된 문자열을 직접 출력해본다.

 

wchar_t 문자열을 출력할 때는 wcout을 이용해야한다.

 

또한 유니코드 문자열을 넣으려면 L"문자열"처럼 지정해야한다

 

#include <iostream>
#include <io.h>
#include <fcntl.h>

using namespace std;

int main(){
	
	wchar_t message_korean[] = L"반갑다 세계야!";
	wchar_t message_chinese[] = L"很高兴认识你世界!";
	wchar_t message_japanese[] = L"うれしい世界だ!";
	wchar_t message_russian[] = L"Приятно познакомиться, мир!";

	cout << "Hello, World!" << endl;

	_setmode(_fileno(stdout), _O_U16TEXT); //윈도우 콘솔 창 유니코드 출력 모드 설정

	wcout << message_korean << endl;
	wcout << message_chinese << endl;
	wcout << message_japanese << endl;
	wcout << message_russian << endl;

	return 0;
}

 

etc-image-5

 

 

 

5. 정수 형식

 

일반적으로 가장 많이 사용하는 데이터 형식

 

양의 정수, 음의 정수, 0

 

정수형은 다른 데이터 형식과는 다르게 조금 특이하게 설정

 

 int는 시스템의 자연스러운 크기를 따르도록 규정

 

여기서 자연스러운 크기는 시스템에서 한번에 처리할 수 있는 크기로, 그러므로 시스템에 따라 int는 크기가 다르다

 

16bit 시스템에서 int는 16bit이고 32bit에서는 32bit이다. 

 

그런데 현재 거의 기본으로 출시되고 있는 64bit컴퓨터에서는 실제로 int는 32bit라고함(4byte)

 

sizeof(데이터형)을 쓰면 해당 데이터형식의 크기를 알 수 있다

 

#include <iostream>
using namespace std;

int main(){

	cout << "short : " << sizeof(short) << " bytes" << endl;
	cout << "unsigned short : " << sizeof(unsigned short) << " bytes" << endl;
	cout << "int : " << sizeof(int) << " bytes" << endl;
	cout << "unsigned int : " << sizeof(unsigned int) << " bytes" << endl;
	
	//MS 전용
	cout << "__int8 : " << sizeof(__int8) << " bytes" << endl;
	cout << "__int16 : " << sizeof(__int16) << " bytes" << endl;
	cout << "__int32 : " << sizeof(__int32) << " bytes" << endl;
	cout << "__int64 : " << sizeof(__int64) << " bytes" << endl;

	cout << "long : " << sizeof(long) << " bytes" << endl;
	cout << "unsigned long : " << sizeof(unsigned long) << " bytes" << endl;
	cout << "long long : " << sizeof(long long) << " bytes" << endl;
	cout << "unsigned long long : " << sizeof(unsigned long long) << " bytes" << endl;

	return 0;
}

 

 

etc-image-6

 

 

__int8같은 데이터형식은 마이크로소프트 비주얼 C++ 컴파일러에서만 동작

 

다른 환경에서는 int8_t같이 수정해야함

 

C++ 언어 표준안은 정수형의 크기를 명시하지는 않지만, 기본적으로 다음과 같다

 

1byte = char <= short <= int <= long <= long long

 

 

 

정수형에서 signed는 음수, 양수를 모두 저장할 수 있다.

 

unsigned는 양수만 저장 가능하다

 

nbit signed는 -2^(n-1) ~ 2^(n-1)

 

nbit unsigned는 0 ~ 2^(n)-1

 

1byte는 당연히 8bit

 

예시:

 

1byte signed : -128 ~ 127

 

1byte unsigned: 0 ~ 255

 

2byte signed: -32768 ~ 32767

 

4byte signed : -2147483648 ~ 2147483647

 

 

 

6. 부동소수점

 

부동이란 "떠다니며 움직인다"라는 뜻으로, 소수점이 고정되지 않고 움직인다는 뜻

 

소수점이 움직인다는 것은 정수부와 소수부의 자릿수가 일정하지 않다는 의미

 

그러나 유효숫자의 자릿수는 정해져있다

 

자료형의 크기가 정해져있으므로 부동소수점의 특정자리까지만 저장할 수 있고 나머지는 유실

 

부동소수점의 정밀도란, 데이터 유실 없이 얼마나 많은 유효 자릿수를 나타낼수 있는지를 말한다

 

#include <iostream>
using namespace std;

int main(){

	cout << 9.87654321f << endl;
	cout << 987654.321f << endl;
	cout << 9876543.21f << endl;
	cout << 0.00000987654321f << endl;
	cout << 0.00000000000987654321f << endl;

	return 0;
}

 

 

etc-image-7

 

 

실행결과는 6자리만 출력되는 것을 알 수 있다

 

cout은 부동소수점 출력할 때 기본 정밀도가 6으로 설정되어있다.

 

6자리까지만 유효하고 나머지는 생략함

 

C++언어의 부동소수점은 IEEE754에서 정의한 형식으로 정의

 

최상위 비트는 부호를 나타내고, 지수와 가수로 나뉨

 

etc-image-8

 

 

부동소수점은 고정소수점보다 넓은 범위의 수를 나타내 계산에 많이 이용되나, 

 

근삿값으로 표현되고 고정소수점 방식보다 연산속도가 느려 별도의 연산장치가 필요함

 

C++에서 숫자 뒤에 f를 붙이면 float, l을 붙이면 long double, 아무것도 붙이지 않으면 double

 

#include <iostream>
#include <iomanip>

using namespace std;

int main(){

	float float_value = 9.87654321f;
	double double_value = 9.87654321987654321;
	long double long_double_value = 9.87654321987654321l;

	cout << "float : " << sizeof(float) << " bytes" << endl;

	//유효자릿수만큼 정밀도 조정
	//setprecision(numeric_limits<float>::digits10 + 1)
	cout << "float_value : " <<
		setprecision(numeric_limits<float>::digits10 + 1) <<
		float_value << endl << endl;

	cout << "double : " << sizeof(double) << " bytes" << endl;
	cout << "double_value : " <<
		setprecision(numeric_limits<double>::digits10 + 1) <<
		double_value << endl << endl;

	cout << "long double : " << sizeof(long double) << " bytes" << endl;
	cout << "long_double_value : " <<
		setprecision(numeric_limits<long double>::digits10 + 1) <<
		long_double_value << endl << endl;

	return 0;
}

 

 

etc-image-9

 

 

 

std::setprecision은 cout에서 출력하는 기본 정밀도를 조절함

 

std::setprecision(std::numeric_limits<데이터형식>::digits10+1);은 특정 데이터 형식이 표현할 수 있는 유효자릿수만큼 정밀도를 조절하겠다는 뜻

 

위 결과를 보면 데이터 형식마다 크기와 출력 자릿수가 다르다

 

4byte : +-1.18*10^(-38) ~ +- 3.4*10^(38), 6~9자리로, 일반적으로 7자리

 

8byte : +-2.23*10^(-308) ~ +-1.80*10^(308), 15~18자리로, 일반적으로 16자리

 

16byte: +-3.36*10^(-4932) ~ +-1.18*10^(4932), 33~36자리

 

 

728x90

'프로그래밍 > C++' 카테고리의 다른 글

C++의 변수 형식 변환  (0) 2025.02.12
L-value와 R-value??  (0) 2025.02.12
C++ 변수 유효 범위  (0) 2025.01.23
C++ iostream, 입출력 cin, cout, 네임스페이스  (0) 2024.12.05
C++ 프로그램 빌드 과정  (0) 2024.11.24