자료형을 변환시켜주는 것
크게 묵시적, 명시적으로 두 가지 형태가 있다.
float f = 10.3f;
printf("%f %e", f, f);
float 자료형은 32bit로, 가수 부분과 지수 부분으로 나뉜다.
예를 들어 149,598,000를 부동소수점 방식으로 표현하면
1.49598(가수 부분) X 10^8(지수 부분) 이렇게 표현 가능하다.
묵시적 형변환의 예
float f = 10.3f;
int i = f;
printf("%f %e %d", f, f, i);
명시적 형변환의 예
float f = 10.3f;
int i = (int)f;
printf("%f %e %d", f, f, i);
float에서 int로의 형변환은 가능하지만, int에서 float로의 묵시적 형변환 시 문제가 발생한다.
float f = 10.3f;
int i = (int)f;
float* pf = &f;
int* pi = (int*)pf;
printf("%f %e %d %d", f, f, i, *pi);
결과: 10.300000 1.030000e+01 10 1092930765
pi의 값은 f의 주소 값을 int형으로 변환한 값으로, *pi
는 10이 출력될 것으로 예상되었는데
왜 *pi의 값은 1092930765란 값이 나온걸까?
float와 int는 동일한 32bit라고 가정했을 때,
f가 가지고 있는 정보는 bit pattern으로 앞에 1.03에 해당하는 부분하고 뒤에 지수 부분이 존재한다.
#include <iostream>
using namespace std;
struct GO {
bool visible;
int pos;
GO(bool visible, int pos) :visible(visible), pos(pos) {}
void print() {
cout << "this: " << this << ", visible: " << visible << ", pos: " << pos << endl;
}
};
struct P : public GO {
float mana;
P() : GO(true, 30), mana(10.3f) {}
void print() {
cout << "mana: " << mana << " ";
GO::print();
}
};
struct E : public GO {
int direction;
float hp;
E(bool visible, int pos) : GO(visible, pos), direction(0), hp(30.0f) {}
void print() {
cout << "direction: " << direction << ", hp: " << hp << " ";
GO::print();
}
};
int main()
{
P p;
E e(false, 100);
p.print();
e.print();
GO g1 = p;
GO g2 = e;
g1.print();
g2.print();
return 0;
}
#include <iostream>
using namespace std;
struct GO {
bool visible;
int pos;
GO(bool visible, int pos) :visible(visible), pos(pos) {}
void print() {
cout << "this: " << this << ", visible: " << visible << ", pos: " << pos << endl;
}
};
struct P : public GO {
float mana;
P() : GO(true, 30), mana(10.3f) {}
void print() {
cout << "mana: " << mana << " ";
GO::print();
}
};
struct E : public GO {
int direction;
float hp;
E(bool visible, int pos) : GO(visible, pos), direction(0), hp(30.0f) {}
void print() {
cout << "direction: " << direction << ", hp: " << hp << " ";
GO::print();
}
};
int main()
{
P p;
E e(false, 100);
p.print();
e.print();
GO* g1 = &p;
GO* g2 = &e;
g1->print();
g2->print();
return 0;
}
Compile Error
int main()
{
P p;
E e(false, 100);
p.print();
e.print();
E* e1 = &p;
e1->print();
return 0;
}
강제 형변환
int main()
{
P p;
E e(false, 100);
p.print();
e.print();
E* e1 = (E*)&p;
e1->print();
return 0;
}
c++에서 명시적 형변환을 시도한다면
int main()
{
P p;
E e(false, 100);
p.print();
e.print();
E* e1 = reinterpret_cast<E*>(&p);
e1->print();
return 0;
}
int main()
{
P p;
E e(false, 100);
p.print();
e.print();
GO* g[2] = {&p, &e};
for(int i=0; i<2; i++) g[i]->print();
return 0;
}
int main()
{
GO* g[2] = { new P, new E(false, 100)};
for(int i=0; i<2; i++) g[i]->print();
return 0;
}
#include <iostream>
using namespace std;
struct GO {
bool visible;
int pos;
GO(bool visible, int pos) :visible(visible), pos(pos) {}
virtual void print() {
cout << "this: " << this << ", visible: " << visible << ", pos: " << pos << endl;
}
};
struct P : public GO {
float mana;
P() : GO(true, 30), mana(10.3f) {}
void print() override{
cout << "mana: " << mana << " ";
GO::print();
}
};
struct E : public GO {
int direction;
float hp;
E(bool visible, int pos) : GO(visible, pos), direction(0), hp(30.0f) {}
void print() override{
cout << "direction: " << direction << ", hp: " << hp << " ";
GO::print();
}
};
int main()
{
GO* g[2] = { new P, new E(false, 100)};
for(int i=0; i<2; i++) g[i]->print();
return 0;
}