캐스트 연산자
캐스트 연산자는 어떠한 자료형을 다른 자료형으로 변환하는 연산자입니다.
여기서는 C 문법에 해당하는 캐스트 연산자만 다룹니다.
묵시적 변환
#include <stdio.h>
int main(int argc,char** argv)
{
int IntValue;
float FloatValue = 30.5f;
IntValue = FloatValue;
printf("%d\n",IntValue);
return 0;
}
컴파일러는 미리 정의된 자료형들에 대해서 변환을 할 수 있는 경우에 "묵시적 변환"을 허용합니다.
어느 정도 안전하다고 할 수 있는 변환들이 미리 지정되어 있기 때문에 가능합니다.
위의 예제는 FloatValue 에 30.5라는 값을 넣고, IntValue 에 대입합니다. 분명 둘은 float 과 int 형으로 그 형이 다르지만, 대입이 되었고, 소숫점이 버려졌습니다.
컴파일 하는 과정에서 데이터가 손실 될 수도 있다는 경고가 발생합니다.
명시적 변환
그러나 새롭게 정의된 자료형이나, 기본적으로 서로 변환이 불가능한 자료형들에 대해서는 묵시적 변환이 허용되지 않습니다.
#include <stdio.h>
struct FloatStruct
{
float FloatValue;
};
struct IntStruct
{
int IntValue;
};
int main(int argc,char** argv)
{
float FloatValue = 30.5f;
int* IntPtr;
float* FloatPtr;
// 이 부분은 컴파일 할 수 없습니다.
//FloatPtr = &FloatValue;
//IntPtr = FloatPtr;
FloatPtr = &FloatValue;
IntPtr = (int*)FloatPtr;
printf("%d\n",*IntPtr);
// 이 부분은 컴파일 할 수 없습니다.
//FloatStruct FloatStructValue;
//IntStruct IntStructValue;
//FloatStructValue = ( FloatStructValue )IntStructValue;
return 0;
}
FloatPtr 은 FloatValue 의 포인터값을, IntPtr 은 FloatPtr 을 대입 받습니다.
포인터 간의 대입이며 메모리의 주소를 의미하는 포인터의 크기는 동일하기 때문에 서로 변환하여 대입을 할 수는 있습니다.
- 32bit 에서 32bit, 64bit 에서 64bit
그러나 안전하다고 보장할 수 없기 때문에 묵시적 변환이 허용되지 않습니다.
즉, 변환방법은 있으나 묵시적 변환은 허용치 않는 형태입니다.
- 서로 다른 자료형에 대한 포인터이기 때문에, 이 포인터를 이용하여 자료를 접근시, 그 값이 올바르지 않을 가능성이 존재합니다.
대신 명시적 캐스팅 연산자를 사용할 수 있습니다.
해당하는 변수 이름 앞에 (자료형)을 기입하는것으로 C 스타일의 명시적 캐스팅이 이루어집니다.
(int*)FloatPtr
출력 결과값은 float 의 기록방식과 int 형의 기록형이 완전히 다르기 때문에 알아볼 수 없는 값이 나오게 됩니다.
구조체 간의 변환
아래 주석에는 구조체 변수끼리의 변환을 시도하는 코드가 있습니다.
그러나 구조체로 선언된 자료형은 기본적으로 "변환을 할 수 있는 방법"이 존재하지 않습니다.
따라서 명시적 캐스팅을 사용한다고 하여도 캐스팅을 할 수 없으며 멤버 변수들을 직접 대입하여야만 합니다.
C++에서는 타입 변환 연산자를 오버로딩 하거나, 대입 연산자 오버로딩등의 방법으로 변환 방법을 제공할 수 있습니다. 이러한 경우에는 서로 캐스팅을 할 수 있게 됩니다.