데이터형 변환
11가지 정수형
3가지 부동 소수점형
데이터형을 혼합해 사용하면
데이터형의 불일치를 해결을 위해 데이터형 변환
- 특정 데이터형 변수에 다른 데이터형의 값을 대입
- 수식에 데이터형을 혼합해 사용
- 함수에 매개변수를 전달
대입 구문에서의 데이터형 변환
so_long이 long형이고 thirty가 short형일때
so_long=thirty; // long형 변수에 short형 값을 대입
thirty의 short형 (16비트 값)을 long형 값(32비트 값)으로 확장해 새로운 값을 대입
데이터형 변환 | 문제점 |
double -> float : 큰 부동 소수점을 작은 부동 소수점 | 유효 숫자의 손실 / 범위를 벗어날 경우 예측 불가 |
부동 소수점형을 정수형으로 | 소수부 손실 / 범위를 벗어날 경우 예측 불가 |
long -> short : 큰 정수형을 작은 정수형 | 범위를 벗어날 경우 하위 바이트들만 복사 |
부동 소수점수를 정수형에 대입할 때의 문제점
- 소수부 버림
- float형 값이 너무 클 경우 int형 변수에 온전히 대입 불가 [예측 불가]
#include <iostream>
using namespace std;
int main()
{
cout.setf(ios_base::fixed, ios_base::floatfield);
float tree = 3;
int guess = 3.9832;
int debt = 7.2E12;
cout << "tree= " << tree << endl;
cout << "guess= " << guess << endl;
cout << "debt= " << debt << endl;
return 0;
}
tree가 부동 소수점형 값인 3.0으로 대입
int형 변수 guess에 3.9832를 대입하면
정수부 3만 대입하고 소수부를 버린다.
int형 변수 debt에는 7.2E12라는 큰 값 저장 불가
-> 1634811904 [약 1.6E09]
{}를 사용할 경우의 초기화 변환
변환된 변수가 완벽하게 값을 유지할 수 있다면, 정수형을 다른 정수형이나 부동 소수점형으로 변환할 때 narrawing 허용
-> long 변수를 int 값으로 초기화 가능
const int code=66;
int x=66;
char c1{31325}; //narrowing, 허용 안됨
char c2={66}; //char가 66을 유지할 수 있기 때문에 허용
char c3 {code}; //상수형 int 변수 code가 66이기 때문에 허용
char c4={x}; //x가 상수가 아니기 때문에 허용 안됨
x=31325;
char c5 = x; //초기화에 의해 허용됨
수식에서의 데이터형 변환 [여러가지 데이터형을 혼합하여 사용할 때]
1. 자동데이터형 변환: 어떤 데이터형은 자동으로 데이터형이 변환
2. 어떤 데이터형은 수식에서 다른 데이터형과 혼합하여 사용되었을 때 데이터형이 변환
1. 자동데이터형 변환
정수승급 : bool, char, unsigned char, signed char, short 형 값은 모두 int형으로 변환된다.
short chickens= 20; //첫 번째 행
short ducks = 35; //두 번째 행
short fowl = chickens + ducks; //세 번째 행
-> 세 번째 행 실행시 chickens와 ducks의 값을 int형으로 각각 변환 후 더하고 short형으로 다시 변환해 변수 fowl 대입
[가장 빠르게 처리되는 데이터형은 int형이기 때문에]
- 정수 승급의 예
- short형이 int형보다 크기가 작을 경우 unsigned short형이 int형으로 변환
- short형이 int형과 크기가 같은 경우에는 unsigned short형이 unsigned int형으로 변환
-> unsigned short형이 승급될 때 데이터 손실이 일어나지 않도록 - wchar_t형은 int, unsigned int, long, unsigned long형 중 충분히 큰 첫 번째 데이터형으로 승급
2. 서로 다른 데이터형을 혼합하여 사용할 때
:작은 크기의 데이터형이 큰 크기의 데이터형으로 변환
컴파일러가 검사를 진행하는 순서
- 한쪽 피연산자가 long double형이면 상대편 피연산자를 long double형으로 변환
- 한쪽 피연산자가 double형이면, 상대편 피연산자를 double형으로 변환
- 한쪽 피연산자가 float형이면, 상대편 피연산자를 float형으로 변환
- 피연산자들이 정수형이므로 정수 승급
- 양쪽 피연산자가 모두 signed이거나 모두 unsgined일 경우에 두 피연산자의 상대적 크기에 따라 큰 쪽으로 변환
- 한쪽 피연산자가 signed 이고 다른 쪽이 unsgined일 경우, unsgined 피연산자가 signed 피연산자보다 상대적으로 크다면 unsigned 피연산자의 형으로 변환
- signed 형이 unsigned형의 모든 값을 표현할 수 있다면, unsigned 피연산자가 signed형으로 변환
- 5,6,7에 해당하지 않은 경우 양쪽 피연산자 모두 signed형의 unsgined 버전으로 변환
정수형 타입의 순위
signed 형 : long long, long, int, short, signed char
[char, signed char, unsigned char는 모두 같은 순위로 본다]
[bool형은 가장 낮은 순위]
[wchar_t, char16_t, char32_t는 원형과 같은 순위]
매개변수를 전달할 때의 형 변환
:C++의 함수원형이 제어
함수원형이 매개변수를 제어하는 것을 막을 경우엔 char형과 chosrt형 (signed/unsigned) 정수 승급 수행
C와의 호환성을 위해 float형 매개변수를 double형으로 변환하여 전달
데이터형 변환자
:강제로 데이터형의 변환
thron변수에 저장된 int형 값을 long형으로 강제 변환
(long) thorn //thorn의 long형 변환을 리턴
long (thorn) //thorn의 long형 변환을 리턴
->데이터형 변환자는 thorn 변수 자체는 변경하지 않고 새로운 값을 만든다.
cout<< int('Q'); //'Q'에 해당하는 정수 코드를 디스플레이한다.
즉, 일반화하면
(typename) value //value를 typeNmae형으로 강제로 변환한다.
typename (value) //value를 typeName형으로 강제로 변환한다.
1. C에서 사용하는 방법
2. C++에서 사용하는 방법이며 함수 호출과 비슷하게 표현
->사용자 정의 클래스를 위해 설계하는 데이터형 변환
[제한적인 4개의 데이터형 변환 연산자 도입 -> 15장에서]
static_cast<>연산자는 어떤 수치 데이터형을 다른 수치 데이터형으로 변환하는 데 사용
static_cast<typeName> (value) //value를 typeName형으로 변환
일반화
static_cast<typeName> (value) //value를 typeName형으로 변환
조류와 동물들의 정수형 개체 수를 구하는 프로그램
auks에 대한 계산 : 두 개의 부동 소수점수를 더하고 그 합을 int형으로 변환해 auks로 대입
[bats와 coots에 대한 계산은
데이터형 변환자를 사용해 두 개의 부동 소수점수를 int형으로 변환한 후 더해 bats와 coots에 대입]
[데이터형 변환자를 사용해 char형 값을 그에 해당하는 ASCII 코드로 출력하는 방법]
#include <iostream>
using namespace std;
int main()
{
int auks, bats, coots;
// 다음 구문은 두 값을 double형으로 더한 후에
// 그 합을 int형으로 변환하여 대입한다
auks = 19.99 + 11.99;
// 다음 두 구문은 두 값을 int형으로 변환한 후에 더한다
bats = (int)19.99 + (int)11.99; //C 스타일
coots = int(19.99) + int(11.99); //C++ 스타일
cout << "바다오리 = " << auks << ", 박쥐 = " << bats;
cout << ", 겸둥오리 = " << coots << endl;
char ch = 'Z';
cout << "코드 " << ch << " 의 값은 "; //char형으로 출력
cout << int(ch) << endl; //int형으로 출력
cout << "코드 Z의 값은 ";
cout << static_cast<int>(ch) << endl; //int형으로 출력
return 0;
}
-> auks : 19.99와 11.99=31.98, 소수부가 버려지고 31만 대입
-> 데이터형 변환자를 사용하면 덧셈이 수행하기 전에 소수부가 버려져
-> 19 + 11 = 30이 bats와 coots에 대입된다.
-> 마지막의 cout 구문은 데이터형 변환자를 사용해 char형 값을 int형으로 변환하여 출력
-> 이 구문은 'Z'에 해당하는 값을 문자가 아닌 정수로 출력
이 프로그램에서 데이터형 변환자를 사용하는 이유
1. double형으로 저장하지만 int형으로 계산해야 하는 값들에 데이터형 변환자가 사용
[부동 소수점수들을 정수값으로 모델링해야 하는 계산]
2. 특정 목적에 맞게 강제로 데이터형을 변환한다.
char형 변수 ch에는 문자 Z에 대한 코드가 들어 있지만
ch를 int형으로 강제로 데이터형을 변환하고 cout 구문을 사용하면 ch에 저장한 ASCII코드를 출력
C++11에서의 auto 선언
9장에서의 auto
초기화 선언시 데이터형을 쓰지 않고 auto를 사용할 수 있다.
auto n =100; //n은 int
auto x =1.5; //x은 double
auto y =1.3e12L; //y는 long double
-> 데이터형을 추론하는 것에 문제가 있을 수 있다.
auto x=0.0; //0.0이 double이기 때문에 문제가 없음
double y=0; //0이 자동으로 0.0으로 변환되기 때문에 문제가 없음
auto z=0; //0이 int이기 때문에, z가 int가 되어 문제가 생김
-> 자동 형변환의 경우에는 문제가 발생
-> 자동으로 변수형을 추론하는 건 STL같은 변수형을 다룰 때 유용하다.
std :: vector<double> scores;
std :: vector<double> :: iterator pv = scores.begin();
std :: vector<double> scores;
auto pv = scroes.begin();
'Programming > C++ 2' 카테고리의 다른 글
[C++] 10장-2. 추상화와 클래스 (0) | 2021.04.11 |
---|---|
[C++ 요약] 3장. 데이터 처리 (0) | 2021.04.09 |
[C++ 연습문제] 3장. 데이터 처리 (1) (0) | 2021.04.09 |
[C++ 요약] 3장. 데이터 처리 (0) | 2021.04.09 |
[C++ 연습문제] 2장. C++ 시작하기 (2) (0) | 2021.04.08 |