반응형

정수와 부동 소수점 등 다른 자료형끼리 값을 계산시키면 어떻게 될까 자료형과 규칙에 대해 설명한다.

산술 변환

지금까지 계산식을 여러번 사용해 왔지만, 실제 프로그래밍에서는 연산식의 피연산자에 변수를 이용하는 경우가 많이 있는데, 그 변수가 반드시 동일한 자료형은 아니다. 예를 들어 계산식의 연산으로 int 형과 float 형의 연산이 행해진 경우는 어떻게 될까? C 언어에서는 이 같은 다른 형태의 연산을 해도 문법적으로는 틀린 것은 아니다.

피연산자는 계산식 중에서 큰 자료형에 맞게 변환된다는 규칙이 있다. 만약 사이즈가 큰 자료형을 작은 자료형으로 변환하면 상위 비트를 제거하게 되므로 정보를 잃어 버릴 가능성이 있다. 그러나 사이즈를 확장하는 경우는 정보를 잃지 않는다. 또한, int 형 이하의 사이즈의 자료형은 계산식에 의해 int 형(즉, 컴퓨터 연산에 사용하는 정수 사이즈)으로 변환된다. 이것은 평소 프로그래머가 의식할 필요는 없지만, 알아두면 손해는 없을 것이다.

이러한 연산식의 변환을 산술 변환이라고 한다. 변환 규칙을 정리하면 표1과 같이 된다.

표1 산술 변환의 법칙


코드1

#include <stdio.h>

int main() {
    char chVar = 50;
    int iVar = 100;
    float fVar = .555;

    printf("%g\n" , chVar + iVar + fVar);
    return 0;
}

이 프로그램에슨 printf() 함수의 인수부에 chVar + iVar + fVar라는 연산을 하고 있는데, 이러한 변수는 모두가 다른 자료형이다. 그래서 산술 변환이 되어 최종적으로는 가장 큰 사이즈인 float 형으로 변환된다. char 형과 int 형의 값은 float형으로 변환되어 정보 손실은 없다. 최종적으로는 150.555이라는 결과를 얻을 수 있을 것이다.

대입 변환

계산식에서 다른 자료형의 피연산자가 있으면 산술 변환을 수행했는데, 계산의 결과를 대입하는 변수가 연산 결과의 자료형과 동일하지는 않는다.

대입의 경우에도 자료형이 다른 경우는 암시적으로 변환하여 대입된다. 이것을 대입 변환이라고 한다. 이 때 변수의 사이즈가 계산식의 자료형보다 큰 경우는 아무런 문제가 없다. 계산 결과 자료형보다 큰 사이즈로 변환하면, 손실되는 정보가 없기 때문이다.

코드2

#include <stdio.h>

int main() {
    char chVar = 100;
    int iVar = chVar;

    printf("iVar = %d\n" , iVar);
    return 0;
}

코드2는 char 형 변수를 int 형 변수에 대입하고 있다. 이 경우 char 형 변수 chVar값이 int로 확장될 것이다. 원래 사이즈보다 확장된 변환의 경우, 정보 손실이 아니기 때문에 문제가 없다.

그러나 반대로 왼쪽의 변수 자료형이 우변보다 사이즈가 작은 경우에는 문제가 있다. 이 경우에도 오류가 발생하지 않지만 값은 정보의 일부를 손실되어 대입된다. 예를 들어 int에서 char로 변환된 경우 상위 비트가 잘려서 대입된다.

코드3

#include <stdio.h>

int main() {
    int iVar = 0xABCD;
    unsigned char chVar = iVar;

    printf("chVar = %X\n" , chVar);
    return 0;
}

코드3에서는 int 형 변수 iVar를 char 형 변수 chVar에 대입하고 있다. 이 경우 자료형이 다르기 때문에 대입 변환이 적용되는데, int 형에서 char 형으로의 변환에 문제가 발생한다. char 형는 int 형보다 사이즈가 작기 때문에, 이 경우는 축소 변환되어 버린다. 따라서 8비트 이상의 상위 바이트는 절단되기 때문에 그 결과 일부 정보를 잃게 된다.

int 형이 32비트라고 가정하면 iVar 값은 2진수로 0000 0000 0000 0000 1010 1011 1100 1101이다. 이 8비트인 char 형으로 변환한 경우, 상위 비트가 버려지고 1100 1101이 된다. 그 결과, 이 프로그램은 16진수 CD를 표시하는 것이다. 만약 부동 소수점에서 정수로 변환이 이루어진 경우, 소수의 정보가 손실된다.

"정보가 손실된다"라고 표현하면 뭔가 나쁜 것처럼 느껴지지만, 하위 8비트를 얻어려는 경우와 부동 소수점의 정수 부분만을 추출하고자 하는 경우에는 이러한 축소 변환이 유용하다. 경우에 따라 잘 이용할 수 있도록 해보자.

형변환

지금까지의 산술 변환 및 대입 변환은 암시적 변환이었다. 그러나 지정된 형으로 값을 변환하도록 프로그래머가 전하는 명시적 변환 방법도 존재한다. 이것을 형변환(type casting)이라고 한다. C 언어에서 어떤 형을 다른 형으로 강제로 변환할 수 있다. 형변환을 사용하려면 다음과 같은 구문을 사용한다.

형변환식

(변환하는 형 이름)값

형을 변환하는 형 이름으로 지정하고 그 형식으로 변환하는 값을 지정한다. 값은 지정된 형으로 변환되고, 대입하는 곳와 함수의 인수로써 전달될 수 있다.

코드4

#include <stdio.h>

int main()
{
    float fVar = 12.34f;

    printf("전체 = %g\n" , fVar);
    printf("실수 = %d\n" , (int)fVar);
    printf("소수 = %g\n" , fVar - (int)fVar);

    return 0;
}

코드4는 타입 캐스팅을 이용하여 부동 소수점 변수 fVar에서 실수와 소수을 얻어내고 있다. 이 처럼 캐스트를 이용하면 작은 형으로 변환할 수 있기 때문에 상위 비트를 잘라내고, 소수점 형을 정수형으로 변환하는 것이 가능하다.


반응형

+ Recent posts