C, C++ 문법

cast 연산자 사용하여 signed , unsigned 상호 형변환시 매우 주의가 필요

디버그정 2011. 7. 21. 17:45

부호 없는 수, 부호 없는 수를 형 변환하거나 형 확장시에 매우 주의해야 된다.
문자열 관련 처리를 하는 과정에서 각각의 1바이트 char형 문자들을 계산하기 편하게 4바이트로 확장시켜서 연산을 하는데
의도하지 않았던 결과가 나와서 디버그해보니 그동안 형 변환에 대해 좀 착각해왔음을 알 수 있었다.


char a = 0xB1; // ( 128보다 크므로 실제로는 음수값이다.)
unsinged int b = (unsigned int)a; 혹은
unsinged int b = a;

여기서 b에는 0xB1이 아니라 0xFFFFFFB1 값이 들어간다.
일단 int형으로 변환을 먼저 시킨 후 unsigned로 변환하는 듯 하다.
위에서 b에 0xB1 값을 대입하고자 하는 목적인 경우에는

unsigned int b = (unsinged int)(unsigned char)a;  // 정규적인 표현
또는
unsigned int b = (unsigned char)a;  // 자동으로 형변환해주므로
이렇게 작은 단위의 형을 먼저 unsigned로 캐스트 연산해줘야 된다.


다음으로 주의해야 될 점이 대입식에서 우변이 실제로는 음수인 경우이다.

char a = 200;
int b = a;

이 경우 b에는 200이 들어갈 거라 착각하기 쉽다.
그러나 a는 실질적으로 음수 값 -56이다.(-128 ~ 127까지 가능)  헥스값은 0xC8이다.
b에도 양수 200이 아닌 -56이 들어가게 된다. 헥스값은 0xFFFFFFC8이다.

char a = 200; 는 엄밀히 말해서 char 표현 범위를 벗어나니 좋은 표현이 아니다.
실질적으로 char a = (char)200; 이런 형변환이 묵시적으로 일어난다.


이런 결과들을 토대로 다음과 같은 사항을 유념해야 된다.
unsigned로 형 확장시에 반드시 작은 단위의 형을 먼저 (unsigned 작은 단위) 캐스트 연산해야 된다.
가급적 표현 범위를 벗어나는 식은 사용하지 말자.