데이터형 변환
Type Conversions
- 피연산자의 데이터형을 혼합하여 사용하면 C++는 데이터형의 불일치를 해결하기위해 다음과 같은 상황에서 자동으로 데이터형 변환을 수행한다.
1. 특정 데이터형의 변수에 다른 데이터형의 값을 대입할 경우
2. 수식에 데이터형을 혼합하여 사용할 경우
3. 함수에 매개변수를 전달할 경우
1. 대입 구문에서의 데이터형 변환
Conversion on Initialization & Assignment
- C++에서는 특정 변수에 다른 데이터형의 값을 대입하는 것을 허용하며, 대입되는 값은 대입시킬 변수의 데이터형으로 변환된다.
- 단, 대입되는 값의 데이터형에는 변함이 없고, 대입시킬 때 적절하게 변환된 데이터형의 대입값이 복사되어 대입된다.
- 범위가 작은 데이터형의 값을 범위가 큰 데이터형 변수로 대입할때는 문제가 생기지 않으나, 반대의 경우 아래와 같은문제가 생김
(정밀도 손실 등)
Conversion Type | Potential Problems |
double -> float | 정밀도(유효숫자)의 손실 야기 |
부동소수점 -> 정수형 |
소수부 손실 float형 값이 클 경우, int형 변수에 정수부마저도 온전히 대입될 수 없음 |
큰 정수형 -> 작은 정수형 (예: long -> short) |
원래의 값 중 하위 바이트의 값만 복사되므로 결과를 예측할 수 없게 됨 |
타 데이터 타입 -> boolean type |
0은 false로 0 이외의 값은 true로 대입함 |
2. { } 를 사용할 경우의 초기화 변환 (C++11)
Initialization Conversions When { } Are Used (C++11)
- 리스트 초기화 (List Initialization) * 를 이용할 경우, Narrow conversions (Narrowing) * 를 방지하여 타입의 암시적 변환을 방지할 수 있다.
리스트 초기화시, 허용되지 않는 데이터형 변환
- float type -> integer type
- integer type -> float type
- long double type -> double / float type
- double type -> float type
- integer type / unscoped 열거형 type -> 원본값을 전부 표현하지 못하는 integer type
- 변수를 이용한 초기화 (컴파일러가 판단하기에 변수는 언제나 큰 값을 가질 가능성이 있고, 초기화 할 당시까지 변수가 어떠한 값들로 변화되어 왔는지까지 확인하는 것은 컴파일러의 소관이 아니므로)
- 이외에 해당 변수의 데이터 타입의 coverage를 벗어나는 상수를 대입할 경우
Example. Narrowing
char c1{66}; // Allow, char형의 coverage내에 있는 상수
char c2{31325}; // Not allow, char형의 coverage를 넘어선 상수
const int Cons = 66; // Cons : 상수
int Vari = 66; // Vari : 변수
char c3 {Vari}; // Not allow, 변수로의 초기화는 허용하지 않음
char c4 {Cons}; // Allow, 기호상수로의 초기화는 허용
* 리스트 초기화 : 중괄호를 이용한 초기화 방법
Example. List initialization
int num {135}; // List initialization
* Narrow Conversions (Narrowing)
- 형변환시, 보다 큰 coverage를 가진 데이터 형에서 작은 coverage의 데이터 형으로의 변환
- 데이터가 손실되거나 변형될 가능성이 높다.
3. 수식에서의 데이터형 변환
Conversions in Expressions
1) 정수 승급 (Integral Promotion)
- 연산 과정에서 Opreand들을 int 타입으로 변환한 다음 연산을 진행시키고, 마지막으로 대입 연산시에만 해당 데이터형으로 변환시켜서 대입하는 방법
- 컴퓨터 내부에서 가장 자연스럽고 빠르게 연산되는 data type이 int 형이기 때문
Example. Integral Promotion
short A = 135; // 135가 short type 변수 A 에 저장됨
short B = 246; // 246이 short type 변수 B 에 저장됨
short C = A + B;
// A와 B가 int type으로 형변환
// 덧셈 연산 수행
// 덧셈 연산의 결과가 다시 short type으로 형변환
// 형변환된 결과값이 C에 대입
2) 데이터 타입이 혼합된 산술식에서의 데이터형 변환
- 하나의 연산데 두 가지 데이터형이 존재할 경우, 작은 coverage의 데이터형이 큰 coverage의 데이터형으로 변환된다.
컴파일러가 수식에서 데이터형 변환의 필요성을 검사하는 기준(C++11)
1. coverage가 가장 큰 피연산자가 long double형이면, 상대편 피연산자를 long double형으로 변환시킨다.
2. coverage가 가장 큰 피연산자가 double형이면, 상대편 피연산자를 double형으로 변환시킨다.
3. coverage가 가장 큰 피연산자가 float형이면, 상대편 피연산자를 float형으로 변환시킨다.
4. 그렇지 않을 경우, 피연산자들이 정수형일 것이므로 정수 승급이 일어남
5. 이 경우, 양쪽 피연산자가 모두 signed이거나 모두 unsigned일 경우에 두 피연산자의 상대적 크기에 따라 큰 쪽으로 변환된다.
6. 반면에 한 쪽은 signed, 다른 한 족은 unsigned일 경우, unsigned 피연산자가 signed 피연산자보다 상대적으로 클 경우엔 unsigned 피연산자로 변환시킨다.
7. 그렇지 않고 signed형이 unsigned형의 모든 값을 표현할 수 있다면, unsigned피연산자가 signed형으로 변환된다.
8. 5, 6, 7중 아무것도 해당되지 않을 경우, 양쪽 피연산자 모두 signed형의 unsigned버전으로 변환된다.
정수형 타입간 순위
- long long, long, int, short, signed char (unsigned 형도 이와 마찬가지)
- char, signed char, unsighend char 간에는 순위차이가 없다. (모두 같은 순위)
- bool형은 가장 낮은 순위를 갖는다.
- wchar_t, char16_t, char32_t는 그들의 근원형과 같은 순위를 갖는다.
4. 매개변수를 전달할 때의 데이터형 변환
Conversions in Passing Arguments
- 추후 내용 기재
5. 데이터형 변환자
Type Casts
- 데이터형을 강제로 변환시키는 방법
// 아래 코드에서 value는 변수 혹은 상수를 의미한다.
(typeName) value;
// value를 typeName형으로 강제 변환 (C Style)
typeName (value);
// value를 typeName형으로 강제 변환 (C++ Style)
static_cast<typeName> (value);
// value를 typeName형으로 강제 변환 (C++ Style)
// 수치 데이터형에서 수치 데이터형으로의 변환에 사용
// 출력 예시
using namespace std;
double num = 10.99;
cout << int (num) << endl;
// 숫자 10 이 출력됨
cout << int (10.99) << endl;
// 숫자 10이 출력됨