기본 데이터 타입
이제부터는 C++ 언어가 데이터를 다루는 방법에 대해 본격적으로 탐구할 시간입니다.
우리가 일상생활에서 다양한 종류의 정보(숫자, 글자, 참/거짓 등)를 사용하듯이, 컴퓨터 프로그램도 숫자, 문자, 논리 값 등 여러 형태의 데이터를 처리해야 합니다.
C++에서는 이러한 데이터의 종류를 구분하기 위해 데이터 타입(Data Type) 이라는 개념을 사용합니다.
이 장에서는 C++이 기본적으로 제공하는 데이터 타입들에 대해 자세히 알아보고, 각 타입이 어떤 종류의 데이터를 저장하며 메모리에서 얼마만큼의 공간을 차지하는지, 그리고 어떤 범위의 값을 표현할 수 있는지 이해하는 데 중점을 둘 것입니다.
데이터 타입이란 무엇인가?
데이터 타입은 프로그램이 데이터를 해석하고 처리하는 방식을 결정하는 속성입니다.
변수를 선언할 때 특정 데이터 타입을 지정하면, 컴파일러는 해당 변수가 어떤 종류의 데이터를 저장할지, 얼마나 많은 메모리 공간을 할당해야 할지, 그리고 그 데이터를 어떻게 연산해야 할지를 알게 됩니다.
예를 들어, 숫자 10을 저장한다고 할 때, 이 10이 정수 10인지, 아니면 10.00과 같은 실수 10인지에 따라 컴퓨터는 내부적으로 다른 방식으로 저장하고 처리합니다.
데이터 타입은 이처럼 데이터의 본질과 그것을 다루는 규칙을 명시하는 역할을 합니다.
정수 타입 (Integer Types)
정수는 소수점 이하가 없는 숫자를 의미합니다.
C++에서는 다양한 크기의 정수 타입을 제공하여, 필요에 따라 효율적으로 메모리를 사용할 수 있도록 합니다.
타입 | 크기 (바이트) | 값의 범위 (약) | 설명 |
---|---|---|---|
char | 1 | -128 ~ 127 또는 0 ~ 255 | 단일 문자 또는 작은 정수 값 저장. 문자 인코딩에 사용. |
short | 2 | -32,768 ~ 32,767 | 작은 정수 값 저장. |
int | 4 | -2,147,483,648 ~ 2,147,483,647 | 가장 일반적으로 사용되는 정수 타입. 시스템에 따라 크기 변동 가능. |
long | 4 또는 8 | int 와 동일하거나 더 넓은 범위 | int 와 동일하거나 더 큰 정수 값 저장. |
long long | 8 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | 매우 큰 정수 값 저장. |
크기(바이트)와 범위: 위 표의 크기와 범위는 일반적인 시스템에서의 값이며, C++ 표준은 int
가 short
보다 크거나 같고, long
이 int
보다 크거나 같고, long long
이 long
보다 크거나 같다고만 명시합니다. 즉, 정확한 크기는 컴파일러와 운영체제, 하드웨어 아키텍처에 따라 달라질 수 있습니다. 하지만 현대 대부분의 시스템에서는 위 표와 같은 크기를 가집니다.
부호 있는 정수와 부호 없는 정수:
위에서 설명한 정수 타입들은 기본적으로 부호 있는(signed) 정수입니다. 즉, 양수와 음수를 모두 표현할 수 있습니다. 만약 음수를 표현할 필요가 없고 오직 양수와 0만을 저장할 것이라면, unsigned
키워드를 붙여 부호 없는(unsigned) 정수 타입을 사용할 수 있습니다.
unsigned
키워드를 붙이면 음수를 표현하는 데 사용되던 비트(bit)를 양수 범위 확장하는 데 사용하므로, 0부터 시작하여 기존 부호 있는 정수보다 두 배 넓은 양수 범위를 가집니다.
unsigned char
: 0 ~ 255unsigned short
: 0 ~ 65,535unsigned int
: 0 ~ 4,294,967,295unsigned long
: 0 ~ 4,294,967,295 (4바이트 기준) 또는 0 ~ 18,446,744,073,709,551,615 (8바이트 기준)unsigned long long
: 0 ~ 18,446,744,073,709,551,615
#include <iostream>
#include <limits> // 각 타입의 최대/최소 값을 확인하기 위해 포함
int main() {
char singleChar = 'A'; // 단일 문자 저장
short smallNumber = 100;
int integerValue = 12345; // 가장 일반적으로 사용
long bigNumber = 1234567890L; // L 접미사는 long 타입을 명시 (선택적)
long long veryBigNumber = 9876543210987654321LL; // LL 접미사는 long long 타입을 명시
unsigned int positiveOnly = 4000000000U; // U 접미사는 unsigned 타입을 명시
std::cout << "char: " << singleChar << " (크기: " << sizeof(char) << "바이트)" << std::endl;
std::cout << "short: " << smallNumber << " (크기: " << sizeof(short) << "바이트)" << std::endl;
std::cout << "int: " << integerValue << " (크기: " << sizeof(int) << "바이트)" << std::endl;
std::cout << "long: " << bigNumber << " (크기: " << sizeof(long) << "바이트)" << std::endl;
std::cout << "long long: " << veryBigNumber << " (크기: " << sizeof(long long) << "바이트)" << std::endl;
std::cout << "unsigned int: " << positiveOnly << " (크기: " << sizeof(unsigned int) << "바이트)" << std::endl;
// 각 타입의 최대/최소 값 확인 (limits 헤더 필요)
std::cout << "int 최대값: " << std::numeric_limits<int>::max() << std::endl;
std::cout << "int 최소값: " << std::numeric_limits<int>::min() << std::endl;
std::cout << "unsigned int 최대값: " << std::numeric_limits<unsigned int>::max() << std::endl;
return 0;
}
sizeof
연산자는 특정 데이터 타입이나 변수가 메모리에서 차지하는 바이트 크기를 알려줍니다.
std::numeric_limits
는 <limits>
헤더에 정의된 템플릿 클래스로, 각 숫자 타입의 최소/최대값 등 다양한 정보를 얻을 수 있게 해줍니다.
부동 소수점 타입 (Floating-Point Types)
부동 소수점 타입은 소수점이 있는 숫자(실수)를 저장하는 데 사용됩니다. 정수 타입과 달리, 실수는 컴퓨터 내부에서 약간의 오차를 가질 수 있습니다.
타입 | 크기 (바이트) | 유효 숫자 자릿수 (약) | 값의 범위 (약) | 설명 |
---|---|---|---|---|
float | 4 | 6 ~ 7 자리 | $\pm 3.4 \times 10^-38$ ~ $\pm 3.4 \times 10^38$ | 단정밀도 부동 소수점. 일반적으로 부족. |
double | 8 | 15 ~ 17 자리 | $\pm 1.7 \times 10^-308$ ~ $\pm 1.7 \times 10^308$ | 배정밀도 부동 소수점. 가장 일반적으로 사용. |
long double | 8, 10 또는 16 | 18 ~ 19 자리 | double 보다 크거나 같음 | 더 높은 정밀도와 넓은 범위를 제공. |
정밀도: 부동 소수점 타입은 '유효 숫자 자릿수'로 정밀도를 표현합니다. float
은 약 67자리의 유효 숫자를, 17자리의 유효 숫자를 표현할 수 있습니다. 더 많은 정밀도가 필요하다면 double
은 약 15long double
을 사용할 수 있습니다. 일반적으로 double
이 가장 널리 사용되며, 대부분의 계산에 충분한 정밀도를 제공합니다.
부동 소수점 오차: 컴퓨터는 실수를 이진수로 표현하기 때문에, 0.1과 같은 일부 십진수 실수는 이진수로 정확히 표현할 수 없습니다. 이로 인해 미세한 오차가 발생할 수 있으며, 이는 부동 소수점 연산에서 주의해야 할 부분입니다.
#include <iostream>
#include <iomanip> // std::fixed, std::setprecision을 사용하기 위해 포함
int main() {
float pi_float = 3.1415926535F; // F 접미사는 float 타입을 명시
double pi_double = 3.14159265358979323846; // 기본적으로 double 타입으로 간주
long double pi_long_double = 3.14159265358979323846L; // L 접미사는 long double 타입을 명시
std::cout << std::fixed << std::setprecision(20); // 소수점 이하 20자리까지 고정 출력
std::cout << "float (pi): " << pi_float << " (크기: " << sizeof(float) << "바이트)" << std::endl;
std::cout << "double (pi): " << pi_double << " (크기: " << sizeof(double) << "바이트)" << std::endl;
std::cout << "long double (pi): " << pi_long_double << " (크기: " << sizeof(long double) << "바이트)" << std::endl;
// 부동 소수점 오차 예시
double result = 0.1 + 0.2;
std::cout << "0.1 + 0.2 = " << result << std::endl; // 정확히 0.3이 아닐 수 있음
return 0;
}
std::fixed
와 std::setprecision
은 <iomanip>
헤더에 정의되어 있으며, 실수를 출력할 때 소수점 이하 자릿수를 제어하는 데 사용됩니다.
문자 타입 (Character Types)
char
타입은 단일 문자를 저장하는 데 사용됩니다.
사실 char
는 1바이트 크기의 정수 타입이기도 하며, ASCII 코드와 같은 문자 인코딩 표준에 따라 특정 정수 값이 특정 문자에 매핑됩니다.
char
: 1바이트. ASCII 문자를 표현하는 데 사용됩니다. (예: 'A', 'a', '1', '@')wchar_t
: 2 또는 4바이트. 유니코드(Unicode)와 같이 더 넓은 범위의 문자 집합을 지원하는 데 사용됩니다. 한글과 같은 다국어 문자를 다룰 때 필요합니다.char16_t
,char32_t
: C++11부터 추가된 유니코드 문자 타입입니다. 각각 16비트와 32비트 유니코드 문자를 표현합니다.
#include <iostream>
int main() {
char grade = 'A'; // 단일 문자는 작은따옴표로 묶습니다.
char asciiValue = 65; // ASCII 코드 65는 'A'입니다.
std::cout << "내 학점: " << grade << std::endl;
std::cout << "ASCII 값 65는 문자: " << asciiValue << std::endl;
// wchar_t 예시 (출력을 위해 별도의 설정이 필요할 수 있습니다)
// wchar_t koreanChar = L'가'; // L 접두사는 wide character를 의미합니다.
// std::wcout << L"한글 문자: " << koreanChar << std::endl;
return 0;
}
논리 타입 (Boolean Type)
논리 타입은 참(true) 또는 거짓(false)이라는 두 가지 값만을 저장합니다.
프로그램의 조건문이나 반복문 등에서 특정 조건의 만족 여부를 판단할 때 사용됩니다.
bool
: 1바이트.true
또는false
값을 가집니다.
#include <iostream>
int main() {
bool isCppFun = true; // 참을 의미하는 true
bool hasErrors = false; // 거짓을 의미하는 false
std::cout << "C++은 재밌는가? " << isCppFun << std::endl; // true는 1로, false는 0으로 출력됨
std::cout << "오류가 있는가? " << hasErrors << std::endl;
// 논리 연산
if (isCppFun) {
std::cout << "아주 재미있습니다!" << std::endl;
} else {
std::cout << "더 노력해야겠네요..." << std::endl;
}
return 0;
}
bool
타입의 값을 std::cout
으로 출력하면 true
는 1
로, false
는 0
으로 표시됩니다. 만약 true
나 false
문자 그대로 출력하고 싶다면 std::boolalpha
조작자를 사용할 수 있습니다.
std::cout << std::boolalpha << "C++은 재밌는가? " << isCppFun << std::endl; // "true"로 출력