C++ 프로그래밍에서 서로 다른 데이터 타입 간에 값을 주고받는 상황은 매우 흔하게 발생합니다. 이때 필요한 것이 바로 타입 변환(Type Conversion)입니다. C++의 타입 변환은 크게 두 가지 방식으로 나눌 수 있습니다.
- 암시적 변환(Implicit Conversion): 컴파일러가 자동으로 수행
- 명시적 변환(Explicit Conversion): 개발자가 의도적으로 지정
1. 암시적 타입 변환 (Implicit Type Conversion)
암시적 타입 변환은 자동 타입 변환이라고도 부릅니다. 사용자가 별도의 코드를 작성하지 않아도, 하나의 표현식 안에 여러 데이터 타입이 섞여 있으면 컴파일러가 스스로 판단하여 변환을 수행합니다.
변환이 일어날 때 모든 피연산자는 표현식 내에서 가장 큰 범위를 가진 타입으로 승격(promotion)됩니다. 승격 순서는 다음과 같습니다.
bool -> char -> short int -> int -> unsigned int -> long -> unsigned long -> long long -> float -> double -> long double
다만 암시적 변환에는 주의점이 있습니다. 작은 타입이 큰 타입으로 변환되는 과정에서 부호 정보가 손실되거나 정밀도가 떨어질 수 있습니다. 예를 들어 unsigned 타입과 signed 타입이 함께 연산되면 의도치 않은 결과가 나올 수 있으므로 주의해야 합니다.
예제 코드
#include <iostream>
using namespace std;
int main() {
int a = 10;
char b = 'a';
a = b + a; // char 'a'(97)가 int로 자동 승격
float c = a + 1.0; // int가 float/double로 자동 승격
cout << "a : " << a << "\nb : " << b << "\nc : " << c;
}실행 결과
a : 107 b : a c : 108
위 코드에서 문자 'a'의 ASCII 값인 97이 정수 10과 더해져 107이 되었습니다. 이처럼 컴파일러가 별도 지시 없이 자동으로 타입을 맞춰주는 것이 암시적 변환입니다.
2. 명시적 타입 변환 (Explicit Type Conversion)
명시적 타입 변환은 흔히 타입 캐스팅(Type Casting)이라고 부릅니다. 개발자가 결과값을 특정 데이터 타입으로 직접 변환하겠다고 선언하는 방식입니다.
C++에서 명시적 변환은 크게 두 가지 방법으로 수행할 수 있습니다.
- C 스타일 캐스팅: 괄호
()안에 변환하고 싶은 타입을 넣는 전통적인 방식 - C++ 캐스팅 연산자:
static_cast,dynamic_cast,const_cast,reinterpret_cast등 타입 안전성을 높여주는 현대적인 방식
일반적으로 컴파일 시점에 타입 검사를 수행하는 static_cast 사용을 권장합니다.
예제 코드
#include <iostream>
using namespace std;
int main() {
double x = 1.574;
int add = (int)x + 1; // C 스타일 캐스팅
cout << "Add: " << add;
float y = 3.5;
int val = static_cast<int>(y); // C++ 스타일 캐스팅
cout << "\nvalue: " << val;
}실행 결과
Add: 2 value: 3
double 타입의 1.574를 int로 캐스팅하면 소수점 이하가 버려져 1이 되고, 여기에 1을 더해 2가 출력됩니다. 마찬가지로 float 타입의 3.5를 int로 변환하면 소수점이 잘려 3이 됩니다. 실수를 정수로 변환할 때는 항상 소수부가 버려짐(절사)에 유의해야 합니다.
정리
- 암시적 변환은 편리하지만, 데이터 손실이나 부호 문제가 생길 수 있어 주의가 필요합니다.
- 명시적 변환은 개발자의 의도를 코드에 분명히 드러내므로, 가능한 한
static_cast같은 C++ 스타일 캐스팅을 사용하는 것이 좋습니다. - 타입 변환 규칙을 정확히 이해하면 예기치 않은 버그를 예방하고 더 안전한 코드를 작성할 수 있습니다.