형변환과 형변환 연산자
정의
- 형변환 : 식의 자료형을 다른 자료형으로 바꾸는 것
- 형변환 연산자 : 명시적으로 형변환을 지시하는 연산자
형변환의 종류
형변환의 종류
| 형변환 종류 |
설명 |
| 명시적 형변환 |
형변환 연산자를 통해 특정 자료형으로 변환 |
| 묵시적 형변환 |
특별히 형변환 연산자를 사용하지 않아도, 연산이 가능한 자료형으로 자동적으로 이루어지는 형변환 |
명시적 형변환
명시적 형변환의 표현 형식
1
2
3
4
| (typename)expr
// typename : 변환할 자료형
// expr : 자료형을 변환할 식 (수식, 변수, 값 등)
// 결과값 : expr 을 typename형으로 변환한 값
|
명시적 형변환의 종류
| 형식 |
변환 대상 자료형 |
설명 |
(typename) |
|
|
(int) |
정수형 (int) |
실수형에서 소수점 이하를 버리고 정수 부분만 취하거나, 다른 정수형으로 변환합니다. |
(float) |
실수형 (float) |
정수형을 단정밀도 실수로 변환하여 사용합니다. |
(double) |
실수형 (double) |
정수형을 배정밀도 실수로 변환합니다. (흔히 나눗셈에 사용) |
(char) |
문자형/정수형 (char) |
값을 1바이트 크기의 문자로 변환합니다. (ASCII/유니코드 값) |
(short) |
정수형 (short) |
값을 2바이트 정수로 변환합니다. |
(long) |
정수형 (long) |
값을 긴 정수형으로 변환합니다. |
(void*) |
포인터 (void*) |
특정 자료형 없이 메모리 주소를 나타내는 범용 포인터로 변환합니다. |
(자료형*) |
포인터 (Type*) |
특정 자료형(int*, struct* 등)의 포인터로 변환합니다. |
예시
1
2
3
4
5
6
7
8
9
10
| void type_cast_operator(){
int a = 3, b = 4;
double c;
c = a / b;
printf("a / b 나눗셈 결과 : %f\n", c);
c = (double)a / b;
printf("(double) a / b나눗셈 결과 : %f\n", c);
}
|
1
2
| b 나눗셈 결과 : 0.000000
(double) a / b나눗셈 결과 : 0.750000
|
위 예시의 두 가지 수식을 풀이하면 다음과 같다.
첫 번째 수식
(1) int a / int b = 3/4
(2) = 0
(3) c = (double) 0
(4) c = 0.000000
두 번째 수식
(1) (double) 3 = 3.000000
(2) 3.000000 / int 4 (명시적 형변환)
(3) 3.000000 / 4.000000 (묵시적 형변환)
(4) c = 0.750000
묵시적 형변환
묵시적 형변환의 정의
- 특별히 형변환 연산자를 사용하지 않아도, 연산이 가능한 자료형으로 자동적으로 이루어지는 형변환
묵시적 형변환의 표현 형식
- 묵시적 형변환은 별도 표현 형식이 없다. 표현하지 않는다.
묵시적 형변환의 종류
| 묵시적 형변환 |
설명 |
승격 (확대변환) Promotion |
가장 효율적인 자료형보다 작은 자료형이 효율적인 처리를 위해 더 큰 자료형으로 변환되는 것. 정수형 승격(integer promotion), 부동소수점 승격(floating point -)이 있다. 정수형 승격 : char, short => 연산시 int 로 자동 승격됨 부동소수점 승격 : float => 연산시 double 로 자동 승격됨 연산 순서에 따라 꼭 필요한 지점에서 형변환 연산지 진행된다. |
| 일반 산술 변환 |
서로 다른 자료형이 혼재하는 식에서 표현 범위가 더 큰 자료형으로 변환됨 컴파일러가 두 피연산자 중 더 큰(높은 순위의) 자료형으로 맞춘다. |
| 대입 변환 |
대입 연산자가 사용될 때, 우변이 좌변의 자료형에 맞춰 자동 변환되는 것. 이 변환은 데이터 손실 가능성이 있다. |
| 함수 호출 변환 |
함수 호출시 입력 인수가 함수의 매개변수 자료형으로 자동 변환되는 것. 대입 변환과 유사하게 작동한다. |
승격과 일반 산술 변환은 다르다.
승격은, “가장 효율적인 연산이 가능한 자료형(int, double)”로 데이터를 처리하기 위함 이며
때문에, 데이터의 손실이 없는 선에서 특정 값 자체를 형변환 시킨다.
때문에 정수형에서는 int 보다 작은 char, unsigned char, short, unsigned short 이 int, unsigned int 형으로 변환되며
부동소수형에서는 double 보다 작은 float 형이 우선 double 형으로 변환된 뒤 연산이 시작된다.
자세한 내용은 아래 예시를 참고한다.
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
| // 1. 승격 확대 변환 (Promotion)
// char c는 **연산에 참여하기 전에** int로 확대 변환된다.
char c1 = 10;
char c2 = 50;
char result_c = c1 + c2;
printf("1. 확대 변환 (char + char): %d\n", result_c);
printf("산술연산이 수행되기 전에, 각 char 는 int 형으로 변환된다.\n");
printf("---------------------------------------------");
printf("(1) result_c = (int)c1 + (int)c2;");
printf("(2) result_c = 10 + 50; (10과 50 모두 int 형)");
printf("(3) result_c = 60; (60은 int 형)");
|
1
2
3
4
5
6
7
| # 출력
1. 확대 변환 (char + char): 60 (char가 int로 변환됨)
산술연산이 수행되기 전에, 각 char 는 int 형으로 변환된다.
---------------------------------------------
(1) result_c = (int)c1 + (int)c2;
(2) result_c = 10 + 50; (10과 50 모두 int 형)
(3) result_c = 60; (60은 int 형)
|
1
2
3
4
5
6
7
8
| // 2. 일반 산술 변환 (Usual Arithmetic Conversions)
// 승격(char -> int) 후, int와 float 중 더 정밀한 float으로 통일된다.
char c = 10;
float f = 20.5f;
float result_a = c + f;
printf("2. 일반 산술 변환 (char + float): %.1f\n", result_a);
printf("(1) char 는 우선 int 형으로 승격된다. 수식은 int + float 이 된다.\n");
printf("(2) int + float 에서 더 정밀한 float 형으로 자료형이 통일된다.");
|
1
2
3
4
| # 출력
2. 일반 산술 변환 (char + float): 30.5
(1) char 는 우선 int 형으로 승격된다. 수식은 int + float 이 된다.
(2) int + float 에서 더 정밀한 float 형으로 자료형이 통일된다.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| // 3. 대입 변환 (Assignment Conversion)
// 큰 double 변수에 작은 float 값을 대입하면 float이 double로 자동 확대 변환된다.
// 이 경우 형변환은 데이터 손실이 없다.
float f = 20.5f;
double d;
d = f;
printf("3. 대입 변환 (float -> double): %.2f (확대 변환)\n", d);
// 작은 int 변수에 큰 float 값을 대입하면 float의 소수점 이하가 버려진다.
// 즉, 데이터 손실이 발생한다.
int small_i;
small_i = f;
printf("3. 대입 변환 (float -> int) : %d (축소 변환, 소수점 버림)\n", small_i);
|
1
2
| 3. 대입 변환 (float -> double): 20.50 (확대 변환)
4. 대입 변환 (float -> int) : 20 (축소 변환, 소수점 버림)
|
1
2
3
4
5
6
7
8
9
| void print_int_to_double(int a){
printf("print int to double : %lf", a);
printf("and how about int..? : %d", a);
}
void main(){
double its_double = 3.14;
print_int_to_double(its_double);
}
|
1
2
| print int to double : 0.000000
and how about int..? : 3
|
Reference
C 프로그래밍 (김형근, 곽덕훈, 정재화 공저)
C 프로그래밍 강의 (방송통신대 - 이병래)
Comments