소년코딩

05.02 - 명시적 형 변환 (Explict type conversion)

이전 포스트 '05.01 - 암시적 형 변환 (Implict type conversion)'에서 컴파일러가 어떤 경우 자료형 간의 값을 암시적으로 변환한다는 것을 배웠다. 한 자료형의 값을 더 큰 자료형으로 승격하려면 암시적 형 변환 시스템을 사용해도 좋다.

초보 프로그래머들은 float f = 10 / 4;와 같은 걸 시도한다. 그러나 10과 4는 모두 정수이므로 "숫자 승격"이 일어나지 않는다. 정수값 나누기 표현식 10 / 4는 2의 값을 생성하고, 그 값은 암시적으로 2.0으로 변환되어 변수 f에 할당된다.

위 같은 경우에는 정수 리터럴 값(Ex. 2, 4)중 하나를 부동 소수점 숫자 리터럴 값(Ex. 2.0, 4.0)으로 바꾸면 나누기는 부동 소수점 숫자 나누기로 수행될 것이다.

하지만 변수를 사용하는 경우 어떻게 될까? 다음 예제를 보자.

int i1 = 10;
int i2 = 4;
float f = i1 / i2;

변수 f의 값은 2로 끝난다. 정수 나누기 대신 부동 소수점 숫자 나누기를 한다고 컴파일러에 어떻게 말할까? 답은 "형 변환 연산자"를 사용해야 한다. 형 변환 연산자를 사용해서 컴파일러에 명시적 형 변환을 하도록 지시해야 한다.


형 변환 (Type casting)

C++에는 C-style cast, static_cast, const_cast, dynamic_cast, 그리고 reinterpret_cast와 같은 5가지 변환 방식이 있다.

이 포스트에서는 C-style caststatic_cast를 다룬다.

C-style cast

표준 C 프로그래밍에서는 ()연산자에 변환할 자료형의 이름을 사용해 형 변환한다.

int i1 = 10;
int i2 = 4;
float f = (float)i1 / i2;

위 프로그램에서는 컴파일러가 i1을 부동 소수점 값으로 변환하기 위해서 (float)을 사용한다. i1은 이제 부동 소수점 값이므로 i2는 부동 소수점 값으로 변환되며, 정수 나누기 대신 부동 소수점 나누기를 수행한다.

C++ 에서는 다음과 같이 함수적인 C-style cast를 사용할 수 있다.

int i1 = 10;
int i2 = 4;
float f = float(i1) / i2;

C-style cast는 컴파일 시간에 검사되지 않으므로 오용될 수 있다. (const를 제거하는 등) 그러므로 C-style cast는 일반적으로 피하는 게 좋다.

static_cast

C++ 에서는 static_cast라는 형 변환 연산자를 도입했다. 이전에 '02.08 - 문자 (char)' 포스트에서 static_cast를 사용하여 charint로 변환하여 std :: coutchar 대신 정수로 출력하도록 했었다.

char c = 'a';
std::cout << static_cast<int>(c) << std::endl; // prints 97, not 'a'

static_cast는 하나의 자료형을 다른 자료형으로 변환하는 데 가장 좋은 방법이다.

int i1 = 10;
int i2 = 4;
float f = static_cast<float>(i1) / i2;

static_cast의 주요 장점은 컴파일 타임에 타입 검사를 제공하여 부주의한 오류를 만들기가 더 어렵다는 것이다. satic_cast는 C-style cast보다 덜 강력하여서 실수로 const를 제거하는 등 의도하지 않은 작업을 할 확률을 줄여준다.

컴파일러는 안전하지 않은 암시적 형 변환을 할 때마다 불평한다.

int i = 48;
char ch = i; // implicit conversion

int(4-byte)를 char(1-byte)로 변환하면 잠재적으로 안전하지 않으므로 컴파일러는 불평한다. 이 형 변환을 사용자가 인지하고 사용한다는 것을 알리기 위해 다음과 같이 형 변환 연산자를 사용하면 된다.

int i = 48;
char ch = static_cast<char>(i);

다음 프로그램에서 컴파일러는 doubleint로 변환하면 데이터 손실이 발생할 수 있다고 불평한다.

int i = 100;
i = i / 2.5;

명시적인 의미를 컴파일러에 알려주면 된다.

int i = 100;
i = static_cast<int>(i / 2.5);

정리 (Summary)

형 변환을 할 때마다 문제가 발생할 가능성이 있으므로 가능하면 형 변환을 피해야 한다. 그러나 피할 수 없는 경우, C-style cast 대신 C++의 static_cast를 사용해야 한다.


cpp 번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/4-4a-explicit-type-conversion-casting/ 입니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기