티스토리 뷰

C, C++

[ C언어 ] 15. 형 변환

RiKang 2017.12.07 12:48

Table of Contents


개요

변수형 변환




1. 개요


 C언어에는 많은 변수형이 존재하며, 상황에 따라 여러 변수형을 혼합해서 사용하는 경우가 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
//code by RiKang, weeklyps.com
#include <stdio.h>
 
int main(void) {
    int a = 3;
    double b = 3.3;
    int c = a+b;
    double d = a+b;
    printf("c = %d\n",c);
    printf("d = %lf\n",d);
    return 0;
}
cs


 이 문서에서는 이처럼 서로 다른 변수형을 같이 이용할 때, 컴파일러가 어떤 식으로 처리하는 지에 대해 다룹니다.




2. 변수형 변환


 C 컴파일러가 판단하는 변수형의 표현 범위 크기는 아래의 순서에 따릅니다. 오른쪽으로 갈수록 표현 범위가 큰 변수형입니다.


char

short

int

long

long long

float

double

long double


 기본적으로 실수형 변수는 소수 표현이 가능하기 때문에 정수형 변수보다 표현 범위가 큰 변수형으로 인식하며, 같은 형식(실수형 or 정수형)의 변수형끼리는 저장 용량 크기가 큰 것이 표현범위가 큰 변수형입니다.


 그러한 이유로, float는 4byte의 용량임에도, 8byte 용량을 가진 long long 보다 표현범위가 크다고 되어있습니다.


 위의 표를 기준으로, 큰 변수형에 작은 변수형의 값을 집어넣을 경우엔 자동으로 변환되어 들어갑니다.


1
2
3
4
5
6
7
8
9
//code by RiKang, weeklyps.com
#include <stdio.h>
 
int main(void) {
    int a = 3;
    long long b=a;
    printf("%lld",b);
    return 0;
}
cs

출력 :

3


 하지만 반대로 작은 변수형에 큰 변수형의 값을 넣을 경우, 컴파일 경고가 발생합니다. 변수형 변환 과정에서 데이터의 손실이 발생할 수 있기 때문이지요. 아래와 같은 경우가 손실이 발생하는 대표적인 예시들입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//code by RiKang, weeklyps.com
#include <stdio.h>
 
int main() {
    // 예시 1. long long -> int
    long long a = 1000000000;
    a = a*a;
    int b = a; // int 형이 담을 수 없는 큰 수이기 때문에 데이터 손실이 발생한다.
    printf("a = %lld, b = %d\n",a,b);
    
    // 예시 2. double -> int
    double c = 3.666;
    int d = c; // int 형은 소수점 아래의 숫자를 표현할 수 없기 때문에 데이터 손실이 발생한다.
    printf("c = %lf, d = %d\n",c,d); // 소수점 아래 숫자는 반올림이 아니라 버림으로 처리된다.
    return 0;
}
cs

출력 :

a = 1000000000000000000, b = -1486618624

c = 3.666000, d = 3


 만일 작은 변수형으로 변환하는 것이 실수가 아니라 프로그래머의 의도라면, 아래의 형식으로 컴파일러에게 그 사실을 알려 줄 수 있습니다.


(변환할 변수형)변수


이렇게 처리하면 더 이상 컴파일 경고는 발생하지 않습니다. 다만, 데이터 손실은 똑같이 일어납니다.


1
2
3
4
5
6
7
8
9
//code by RiKang, weeklyps.com
#include <stdio.h>
 
int main() {
    double c = 3.666;
    int d = (int)c; // 의도적으로 소수를 int 형 변수에 넣는다고 컴파일러에게 알려준다.
    printf("c = %lf, d = %d\n",c,d); // d 에는 소수점 아래 숫자는 버림으로 처리된 값이 저장된다.
    return 0;
}
cs

출력 :

c = 3.666000, d = 3


 (변환할 변수형)변수 를 활용하는 주요 예시는 아래와 같습니다.


예시 1.


 C언어에서 정수를 직접 입력하면 int 형 변수로 취급하기 때문에, 큰 수를 사용할 때에는 (long long) 을 붙여줍니다. 예를 들어, int 의 최대 크기보다 큰 2^40 을 long long 변수에 넣으려면 숫자 앞에 (long long)을 붙여줘야 합니다.


1
2
3
4
5
6
7
8
9
//code by RiKang, weeklyps.com
#include <stdio.h>
 
int main() {
    long long a = 1<<40;  // (int)1<<40 으로 처리되기 때문에 제대로 계산되지 않는다.
    long long b = (long long)1<<40;
    printf("a = %lld, b = %lld\n",a,b);
    return 0;
}
cs

출력:

a = 0, b = 1099511627776


예시 2.


 'int변수/int변수'의 연산을 할 경우, 소수점 아래는 버림 처리가 됩니다. int끼리 나눈 결과를 소수점 아래까지 표현하는 실수형 변수로 받고 싶다면 (double)을 붙여줘야 합니다.


1
2
3
4
5
6
7
8
9
10
//code by RiKang, weeklyps.com
#include <stdio.h>
 
int main() {
    int a = 6, b = 4;
    double c = a/b;        // 버림으로 인해 1.0이 저장된다.
    double d = (double)a/b;// 1.5가 저장된다.
    printf("c = %lf, d = %lf\n",c,d);
    return 0;
}
cs

출력:

c = 1.000000, d = 1.500000


 C언어에서 서로 다른 변수형끼리 연산할 경우, 둘 중 더 큰 변수형에 맞춰서 결과 값을 반환합니다. long long 과 int 의 연산이라면 long long 형의 결과값, char 과 int 의 연산이라면 int형의 결과값이 나오는 식입니다. 따라서 위의 예시2에선 a,b 둘 중 하나에만 (double)을 붙여주어도 결과값으로 double형을 반환하게 됩니다.

'C, C++' 카테고리의 다른 글

[ C언어 ] 17. 문자열 관련 함수  (0) 2018.01.03
[ C언어 ] 16. 포인터  (0) 2018.01.02
[ C언어 ] 15. 형 변환  (2) 2017.12.07
[ C언어 ] 14. 문자열  (0) 2017.12.04
[ C언어 ] 13. 연산자 우선순위  (0) 2017.11.27
[ C언어 ] 12. 배열  (0) 2017.11.25